先看几个例子。
例子一:生成一个1~10的整数列表
list = [1,2,3,4,5,6,7,8,9,10]
或者,
list = range(1,11)
例子二:生成一个1~10的每个整数的平方数的列表
list = []
for num in range(1, 11):
list.append(num*num)
虽然确实是实现了预期的需求,但是需要通过多行代码才能实现,过程非常繁琐,一点都不pythonic。
为了实现类似需求,python提供了一些高级特性来简化,就是列表推导式。
列表推导式(List Comprehensions)是python内置的非常简单且强大的可以用来轻松创建列表(List)的方法。
例子三:用列表推导式创建1~10的所有整数的平方数的列表
>>> list = [num*num for num in range(1,11)]
>>> list
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
可见,列表推导式的书写规则是,生成的元素放在语句前面,紧跟着的是for循环。
而且,在列表推导式的循环后面加上条件判断 。
列子四:创建1~10的所有偶数平方数的列表
>>> list = [num * num for num in range(1,11) if num%2 == 0]
>>> list
[4, 16, 36, 64, 100]
例子五:使用两个for循环将两个列表中的元素进行全排列,继而生成新的列表
>>> list = [char+num for char in ['a', 'b', 'c'] for num in ['1','2', '3']]
>>> list
['a1', 'a2', 'a3', 'b1', 'b2', 'b3', 'c1', 'c2', 'c3']
基于列表继续扩展,如果列表元素的个数持续扩大,达到10万个,如此大的列表将占据巨大的内存。假设程序实际上只需要访问列表中其中的几个元素,那么列表占用的绝大多数内存空间都是多余的,纯属浪费。Python为了解决这个问题,引入生成器(generator)。
可以通过生成器表达式将列表改为一个生成器。列表一旦被创建,其包含的元素就实实在在地存在内存中,占据着内存空间,列表存放的是元素本身,而生成器存放的是算法,通过next()
调用算法实时生成元素,因此生成器占用的内存空间很小。
将列表推导式的方括号[]改为小括号()即可创建一个生成器。
例子六:
>>> g = (num * num for num in range(1,6))
>>> g
<generator object <genexpr> at 0x0000018E0754F228>
>>> next(g)
1
>>> next(g)
4
>>> next(g)
9
>>> next(g)
16
>>> next(g)
25
>>> next(g)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
说明:可以看到,列表list一旦被创建,内存中就存放所有元素,而生成器g的元素内容将随着next()函数的调用实时生成,直到最后没有元素可生成时,抛出StopIteration错误。
除了表达式可以变为生成器之外,函数同样可以变为生成器。
例子七:编写一个函数,通过该函数可以计算出任意自然数的平方数。
#!usr/bin/env python
def square(input):
list = []
for num in range(input):
list.append(num * num)
print(list)
return list
for num in square(5):
print(num)
结果:
[0]
[0, 1]
[0, 1, 4]
[0, 1, 4, 9]
[0, 1, 4, 9, 16]
0
1
4
9
16
说明:可以看到square()
函数在运行过程中会创建一个列表,假设想要计算的自然数变大,那么列表也会变大,此程序便会占据大量的内存,当自然数无限大时,程序将因无法分配到足够的内存而崩溃。
例子八:借助生成器,将square()
函数改为生成器函数。
#!usr/bin/env python
def square(input):
for num in range(input):
print('before yield')
yield num * num
print('after yield')
for num in square(5):
print(num)
结果:
before yield
0
after yield
before yield
1
after yield
before yield
4
after yield
before yield
9
after yield
before yield
16
after yield
说明:
yield
语句返回,再次执行时,从上次离开的地方继续执行。原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。