列表生成式是 Python 内置的非常简单却强大的可以用来创建list的生成式, 一次性生成所有数据,然后保存在内存中,适合小量数据。我们通过以下实例来说明。
1.例如要实现将1-100所有偶数的平方返回,用生成式方法,如下:
li = [x*x for x in range(1,21) if x%2 == 0] # if后面的条件语句用来筛选出偶数
print(li) # 打印出此列表生成式
# 结果
[4, 16, 36, 64, 100, 144, 196, 256, 324, 400]
2.运用列表生成式,可以写出非常简洁的代码。例如,列出当前目录下的所有文件和目录名,可以通过一行代码实现:
import os # 导入os模块
li = [d for d in os.listdir('.')] # os.listdir 可以列出文件和目录
# 结果
['.idea', 'design.py', 'drawn.py', 'guess_num.py', 'my_requests.py', 'my_urlopen.py', 'test.py', 'venv']
3.列表生成式也可以使用两个变量来生成list:
dict = {'x': 'A', 'y': 'B', 'z': 'C' } # 创建一个字典
li = [k + '=' + v for k, v in dict.items()] # 用 items() 函数以列表返回可遍历的(键,值)元组
print(li)
# 结果
['y=B', 'x=A', 'z=C']
通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在 Python 中,这种一边循环一边计算的机制,称为生成器(Generator)。
要创建一个 generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]
改成()
,就创建了一个 generator:
g = (x * x for x in range(10))
print(g)
# 结果
at 0x000000000223C518>
我们可以直接打印出list的每一个元素,但我们怎么打印出generator的每一个元素呢?
如果要一个一个打印出来,可以通过generator的__next__()
方法:
print(g.__next__()) # 0
print(g.__next__()) # 1
print(g.__next__()) # 4
print(g.__next__()) # 9
print(g.__next__()) # 16
print(g.__next__()) # 25
print(g.__next__()) # 36
print(g.__next__()) # 49
print(g.__next__()) # 64
print(g.__next__()) # 81
print(g.__next__())
# Traceback (most recent call last):
File "D:/workspace/spider/test1/test.py", line 28, in
print(g.__next__())
StopIteration
generator 保存的是算法,每次调用__next__()
,就计算出下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出 StopIteration 的错误。
上面这种不断调用next()
方法稍显复杂,正确的方法是使用for
循环,因为 generator 也是可迭代对象:
for n in g:
print(n)
# 结果
0
1
4
9
16
25
36
49
64
81