从python2开始,引入了一个好玩好用的东西就是列表解析式,列表解析式本身是一个语法糖,编译器会优化,不会因为简化而影响了效率,反而因为优化大大提高了效率,因为减少了代码的行数,因此减少了工作量和出错率。减少了代码行数,但是增加了可读性。
列表解析式的语法:[返回值 for 元素 in 可迭代对象 if 条件] 其中if条件语句可选。最终返回一个新的列表。
那么具体怎么使用呢?我们先通过一个简单的小例子来说明。
例如:新建一个列表,取值0~9,将每个元素增加1后求平方返回新的列表。
lst1 = []
for i in range(10):
lst1.append((i+1)**2)
print(lst1)
这就是一个简单的for循环,那么我们把它写成列表解析式:
lst2 = [(i+1)**2 for i in range(10)]
print(lst2)
可以看到不算print语句的话,列表解析式一行就搞定了。大大缩减了代码的行数。那么列表解析式的效率如何呢?
%%timeit
lst1 = []
for i in range(10):
lst1.append((i+1)**2)
5.26 µs ± 76.8 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%%timeit
lst2 = [(i+1)**2 for i in range(10)]
4.65 µs ± 57 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
通过对比可以看到,只是一个简单的for循环语句采用列表解析式就可以省下很多的时间,提高效率。当然列表解析式还可以写出复杂的语句来。
[exper for item in iterable if cond1 if cond2]
例如:20以内既能被2整除又能被3整除的数。
[i for i in range(20) if i%2 == 0 if i%3 == 0]
[exper for i in iterable1 for j in iterable2]
例如:
[[x,y] for x in 'abc' for y in range(3)]
[[‘a’, 0], [‘a’, 1], [‘a’, 2], [‘b’, 0], [‘b’, 1], [‘b’, 2], [‘c’, 0], [‘c’, 1], [‘c’, 2]]
生成器的表达式和列表解析式的样子很像,就是将外面的中括号换成小括号就可以了。(返回值 for i in 可迭代对象 if 条件)返回的是一个生成器,就是一个迭代器,可迭代对象。它和列表解析式不同的是,生成器是按需计算(惰性求值),需要的时候才计算,而列表解析式是立即返回值。
g = ('{:04}'.format(i) for i in range(1,11))
next(g)
for x in g:
print(x,end = " ")
print('~~~~~~~~~~~~')
for x in g:
print(x,end = " ")
0002 0003 0004 0005 0006 0007 0008 0009 0010 ~~~~~~~~
对比列表解析式
g = ["{:04}".format(i) for i in range(1,11)]
for x in g:
print(x,end = ' ')
print('~~~~~~~~~~~')
for x in g:
print(x,end = ' ')
0001 0002 0003 0004 0005 0006 0007 0008 0009 0010 ~~~~~~~
0001 0002 0003 0004 0005 0006 0007 0008 0009 0010
我们可以看到生成器只打印了一次,走完一遍以后就不能回头了。但是呢,因为是按需计算的,所以占用内存极少,而列表解析式是构造返回一个新的列表需要占用内存。