生成式(列表生成式、集合生成式、字典生成式)、生成器
列表生成式
凡是可以通过for-in
循环创建的列表,都可以使用列表生成式来创建
>>> L = [x **2 for x in range(1, 7)]
>>>
>>> L
[1, 4, 9, 16, 25, 36]
可以在列表生成式的for-in循环后面添加if语句
>>> L = [x **2 for x in range(1, 7) if x % 2 == 0]
>>> L
[4, 16, 36]
可以在列表生成式中使用双重循环
>>> L = [(i, j) for i in range(1, 4) for j in range(1, 3)]
>>> L
[(1, 1), (1, 2), (2, 1), (2, 2), (3, 1), (3, 2)]
同样,可以在双重循环后添加if语句
>>> L = [(i, j) for i in range(1, 4) for j in range(1, 3) if i != j]
>>> L
[(1, 2), (2, 1), (3, 1), (3, 2)]
嵌套的列表生成式
>>> L = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> l1 = [[j[i] for j in L] for i in range(3)]
>>> l1
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
集合生成式
和列表生成式类似,通过for-in
循环来创建集合生成式
>>> s = {x **2 for x in range(1, 7)}
>>> s
{1, 4, 36, 9, 16, 25} ##集合是没有顺序的
>>> s = {x **2 for x in range(1, 7) if x % 2 == 0}
>>> s
{16, 4, 36}
>>> s = {(i, j) for i in range(1, 4) for j in range(1, 3)}
>>> s
{(1, 2), (3, 2), (3, 1), (2, 1), (2, 2), (1, 1)}
>>> s = {[i, j] for i in range(1, 4) for j in range(1, 3)}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 1, in <setcomp>
TypeError: unhashable type: 'list' ##集合的元素必须是能hash的
>>> s = {(i, j) for i in range(1, 4) for j in range(1, 3) if i != j}
>>> s
{(1, 2), (3, 2), (3, 1), (2, 1)}
字典生成式
>>> keys = ['a', 'b', 'c']
>>> values = [1, 2, 3]
>>> d = {key:value for key in keys for value in values}
>>> d = {key.upper():value for key in keys for value in values}
>>> d
{'A': 3, 'B': 3, 'C': 3}
>>> d = {key.upper():value for key, value in zip(keys, values)}
>>> d
{'A': 1, 'B': 2, 'C': 3}
>>> d = {key.upper():value
... for key, value in zip(keys, values)
... if value > 2}
>>> d
{'C': 3}
没有元组生成式
生成器
通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator
。
要创建一个generator
,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]
改成()
,就创建了一个generator
:
>>> g = (x * x for x in range(10))
>>> type(g)
<class 'generator'>
可以通过next()
函数来获取生成器的值,当生成器的值被调用完了后,会停止迭代,而不会重头开始重新迭代
>>> g
<generator object <genexpr> at 0x7fa073c008b8>
>>> next(g)
0
>>> next(g)
1
>>> next(g)
4
>>> next(g)
9
>>> next(g)
16
>>> next(g)
25
>>> next(g)
36
>>> next(g)
49
>>> next(g)
64
>>> next(g)
81
>>> next(g)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 289211569@qq.com