目录
列表生成式
有两种方法:
第一种:
L=[]
for x in range(1,11):
L.append(x)
print(L)
这种比较麻烦。
第二种:
L=[x for x in range(1,11)]
print(L)
可以使用列表生成式解决全排列问题:
题目如下:输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
L=[a+b+c for a in 'abc'for b in 'abc' for c in 'abc']
print(L)
print(len(L))
生成器:
通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
第一种方法:
和列表生成式类似,把[]改成()
g=(x for x in range(0,11))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
|
第二种方法:yield
yield生成器和普通函数的执行顺序不一样,普通函数遇到return语句或者最后一句才返回,而生成器函数,在每次调用next()的时候执行,遇到yield语句返回,再次调用next()时接着从上次返回的yield语句处继续执行。
以斐波那契数列为例进行理解:
先把yield看成return
def fib(max):
n, a, b = 0, 0, 1
while n < max:
print('断点1')
yield b
print('断点2')
a, b = b, a + b
print(a,b)
print('断点3')
n = n + 1
print('n',n)
f=fib(6)
print(next(f))
print('*'*20)
print(next(f))
运行结果:
断点1
1
********************
断点2
1 1
断点3
n 1
断点1
1
程序执行顺序:
1、因为fib()函数有yield,所以并不会真正执行,而是生成一个生成器对象。
2、第一次调用next()方法,程序执行到yield,返回b为1.
3、打印‘*’
4、第二次调用next()函数,从上一次返回的yield语句处继续执行,打印a=1,b=1……
执行完毕,继续执行,直到再次碰到yield语句。打印结果如上所示。
5、继续调用next(),也是从上次跳出的地方接着执行。
迭代器
可以直接作用于for循环的数据类型有以下几种:
一类是集合数据类型,如list、tuple、dict、set、str等;
一类是generator,包括生成器和带yield的generator function。
这些可以直接作用于for循环的对象统称为可迭代对象:Iterable。
可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。
可以使用isinstance()判断一个对象是否是Iterator对象
生成器都是Iterator对象,但list、dict、str虽然是Iterable,却不是Iterator。把list、dict、str等Iterable变成Iterator可以使用iter()函数
例:
from collections.abc import Iterator
list=[1,2,3,4]
print(isinstance(list,Iterator))
list=iter(list)
print(isinstance(list,Iterator))
运行结果:
False
True