作者 |Philip Wilkinson
编译 |VK
起源 |Towards Datas Science
在应用 Python 将近一年的工夫里,我常常遇到“生成式”这个词,但我没生成式它的确切含意或它所涵盖的内容。
直到最近,我才发现,有了生成式后,我能够利用列表将我的代码从多行缩短为一行。此外,这种代码缩短办法不仅能够用于列表,还能够用于字典和汇合。
本文试图解释生成式在列表、字典和汇合的适用性,以及它们如何缩小日常编程所需的代码量。
首先,生成式是能够在一行中创立列表、字典和汇合的代码片段。这样就不用为 for 循环应用多行,而且还缩小了应用 map()、filter()和 reduce()函数的须要。
它们由方括号 (依据你要创立的数据类型而定) 组成,其中蕴含一个表达式,后跟一个 for 子句和一个或多个 if 子句。表达式自身能够是任何货色,这意味着你能够将许多不同的对象放入列表中,只有它们是可编辑的。因而,从缩小应用的行数和减少可读性的角度来探讨这些可能对代码产生的影响是值得的。
列表
在 python 中,只需将我的项目放在方括号 ([]) 内,用逗号分隔,就能够创立列表,如下所示。
list1 = [1, 2, 3, "hello", 7.0, 52]
它们通常用于多种目标的编程中,但在长格局中编写或应用 for 循环进行编辑都会很麻烦。首先,在创立列表方面,小列表可能很容易以长格局打印进去,例如:
nums = [1, 2, 3, 4, 5, 6, 7, 8]
但当这个值变长时,即在 0 -50 范畴内,甚至更长,它们可能会变得轻便。它们能够通过 for 循环应用 range 函数轻松创立,如下所示:
nums = []
for i in range(1, 51):
nums.append(i)
print(nums)
# out: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50]
然而咱们能够应用列表生成式将其缩短为一行,并且不须要 append()办法。
nums = [i for i in range(1,51)]
print(nums)
# out: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50]
基本上,for 循环放在一行中,同时初始化列表,从下面的示例中打消了对第一行和第二行代码的须要。
当咱们开始为增加到列表中的数字增加条件时,这就变得更加重要了,比方只容许偶数并且心愿这些数字是平方的。同样,也能够应用 for 循环生成,如下所示:
square_nums = []
for x in range(1,26):
if x % 2 == 0:
square_nums.append(x**2)
print(square_nums)
# out: [4, 16, 36, 64, 100, 144, 196, 256, 324, 400, 484, 576]
然而,同样能够应用列表生成式将其缩短为一行,从而缩小对用于在范畴内循环、创立条件并将后果附加到原始列表的行的须要。
square_nums = [x**2 for x in range(1,26) if x % 2 == 0]
print(square_nums)
#out: [4, 16, 36, 64, 100, 144, 196, 256, 324, 400, 484, 576]
在这里,数字的转换在行首执行 x **2,for 循环在行中执行,对于 x 在范畴(1,26),条件在开端执行,就如同 x%2== 0 一样。这实质上使代码更具可读性,因为所有操作都在一行中执行,并缩小了生成雷同输入所需的代码量。
这还能够缩小 append()、map()、filter()或 reduce()办法在创立新列表时对现有列表进行操作的须要,再次升高代码的复杂性并使其更具可读性。
相似的例子是很容易取得的,更多的信息能够很容易地通过其余文章在媒介,如这里和这里取得。然而,值得注意的是,这些生成式也能够用于字典和汇合。
字典
字典是一个无序的数据汇合,能够扭转和索引,应用大括号和键和值对编写。在这里,键被用来拜访值,并且常常被用来存储信息,这些信息对这些信息是有用的。上面提供了一个示例,例如用于存储分数。
Grades = {
"Steven": 57,
"Jessica": 82,
"William": 42,
"Hussein": 78,
"Mary": 65,
}
print(Grades)
# out: {'Steven': 57, 'Jessica': 82, 'William': 42, 'Hussein': 78, 'Mary': 65}
与列表相似,有时也会很耗时,因而能够应用 for 循环和条件语句来结构,但能够更简略地应用生成式来结构。
例如,对于咱们在下面创立的列表,咱们不仅想晓得数字的平方,而且还想存储原始数字,这样咱们就能够应用它轻松地查找它的平方值。而后,咱们能够简略地创立一个蕴含键值对的字典,其中 key 代表原始数字,value 代表数字的平方。应用 for 循环:
# 初始化空 dict
even_squared_dict = {}
for x in range(1,10):
if x % 2 == 0:
even_squared_dict[x] = x**2
print(even_squared_dict)
# out: {2: 4, 4: 16, 6: 36, 8: 64}
然而应用字典生成式:
even_sqaured_dict = {x: x**2 for x in range(1,10) if x % 2 ==0}
print(even_squared_dict)
# out: {2: 4, 4: 16, 6: 36, 8: 64}
实质上,这个和列表生成式之间的惟一区别是应用大括号来蕴含生成式,并将 x 放在冒号后面,以批示这示意键。
而后,还能够应用它来创立基于现有列表的字典。例如上面,字典生成式用于创立一个字典,其键为三位数的国家代码,值为两位数的国家代码,其中两位数代码与三位数代码的前两位数雷同。
ThreeCharCodes = ["CAN", "FIN", "FRA", "GAB", "HKG", "IMN",
"MCO", "NPL"]
cntryDict = {c: c[:2] for c in threeCharCodes}
print(cntryDict)
# out: {'CAN': 'CA', 'FIN': 'FI', 'FRA': 'FR', 'GAB': 'GA', 'HKG': 'HK', 'IMN': 'IM', 'MCO': 'MC', 'NPL': 'NP'}
汇合
最初,生成式也能够用于创立汇合,汇合是一种不同于列表或元组的数据类型,不能存储同一元素的屡次呈现。
在这样做时,它存储无序值,初始化办法是将一个列表传递给 set()或应用大括号来蕴含由逗号分隔的值(只管空的花括号将初始化字典)。上面提供了一个例子:
Fruits1 = set(["apple", "banana", "cherry", "apple"])
print(Fruits1)
Fruits2 = {"orange", "pear", "grape", "pear"}
print(Fruits2)
# out: {'apple', 'cherry', 'banana'}
{'grape', 'pear', 'orange'}
从这里能够分明地看到,只管向汇合传递了多个 apple 或 pear 值,但只生成了一个实例。同样,能够应用 for 循环生成这些命令,如下所示:
import random
nums = set([])
for x in range(25):
y = random.randint(10,20)
nums.add(y)
print(nums)
# out: {10, 12, 14, 15, 16, 17, 18, 20}
尽管 25 个随机整数在 10-20 之间,但最终输入仅蕴含 8 个惟一值,而不是列表中呈现的 25 个值。同样,应用对汇合的生成式能够更简洁地编写这篇文章。
nums = {random.randint(10,20) for num in range(25)}
print(nums)
# out: {11, 12, 13, 14, 15, 16, 17, 19, 20}
因而,这种生成式与列表生成式的区别在于应用大括号,而不是蕴含生成式的方括号。
与列表和字典生成式相似,这也能够用于现有列表以生成汇合。例如,如果咱们想依据 1.6 的除法将公里改为英里,只须要惟一的值,并将其限度为小于 100 公里的值。
kms = [10, 12, 65, 40, 12, 75, 34, 65, 10, 10, 38, 100, 160, 200]
miles = {d/1.6 for d in kms if d < 100}
print(miles)
# out: {0.625, 0.75, 2.5, 2.125, 4.0625, 4.6875, 2.375}
总结
因而,生成式能够很容易地用于创立新的列表、词典和汇合。应用这些能够缩小生成它们所需的行数,并进步可读性。它们能够用作 append()、map()、filter()或 reduce()函数的替换。
显然,能够将它们放大以执行更简单的生成式,例如应用 lambda 函数、嵌套列表生成式或多条件语句。然而,在这样做时值得注意的是,生成式可能很快变得难以了解,在这种状况下,值得回到创立函数或 for 循环,以便在须要执行多个操作时进步可读性。
原文链接:https://towardsdatascience.co…
欢送关注磐创 AI 博客站:
http://panchuang.net/
sklearn 机器学习中文官网文档:
http://sklearn123.com/
欢送关注磐创博客资源汇总站:
http://docs.panchuang.net/