列表推导式、生成器和迭代器
关键词:列表推导式;生成器;迭代器;实例;可迭代;转换迭代器
在创建一个列表、元组或字典时,如果其元素有规律可循,则可以用while或for循环创建。但是,如果该规律简单时,就没有必要用循环创建了。此时,可以选择用推导时创建。
推导式的结构有两种:
1)表达式1 for 变量 in 表达式2
2)表达式1 for 变量 in 表达式2 if 条件
1. 列表推导式
例如,创建一个1到5的自然数列表
lst = [i for i in range(1,6)]
print(lst) >>[1, 2, 3, 4, 5]
又如,创建一个2到10的偶数列表
lst2 = [2*i for i in range(1,6)]
print(lst2) >>[2, 4, 6, 8, 10]
或者
lst3 = [i for i in range(2,11,2)]
print(lst3) >>[2, 4, 6, 8, 10]
或者
lst4 = [even for even in range(1,11,1) if even % 2 ==0]
print(lst4) >>[2, 4, 6, 8, 10]
或者
lst5 = [2 * j + 2 for j in range(0,5,1)]
print(lst5) >>[2, 4, 6, 8, 10]
注意: 变量是来自表达式2的元素,表达式1式关于变量的表达式,表达式1也可以式变量本身。
2. 生成器
创建一个列表后,列表中的每个元素都要分配一个内存空间用于存储。因此,如果一个列表中有很多元素,而在计算运行时需要用到的仅仅是前面几个元素,那么使用如此庞大的列表对内存的需求太大,浪费存储空间,影响计算速度。
为此,如果能够用一个元素就生成一个元素,就能解决存储空间浪费的问题。解决办法:用生成器。创建生成器有两种方法:
方法1.生成器的创建和列表类似,只是将[]换成()即可。
方法2.生成器函数。
另外,调用方法有两种。举例如下:
如:用列表推导式生成一个自然数
gene1 = (i for i in range(1,9))
print(next(gene1)) >> 1
print(gene1.next()) >> 2
如:用生成器函数生成一个自然数
def fn():
i = 0
while True:
i += 1
yield i
g = fn()
print(next(g)) >> 1 #第一次调用为1
print(next(g)) >> 2 #第二次调用为2
注:如果将函数中的return res改为yield res,则该函数就叫生成器函数。
2.1 用type()函数查看生成器的类型
如:
def fn():
i = 0
while True:
i += 1
yield i
g = fn()
print(type(g)) >> <class ‘generator’>
2.2 用isinstance(a,b)函数判断一个对象a是否是另一个对象b的实例
如:print(isinstance(1,int))
print(isinstance(1,int)) >> True #整数实例
print(isinstance(‘1’,str)) >> True #字符串实例
print(isinstance([1,2],list)) >> True #列表实例
print(isinstance((1,2),tuple)) >> True #元组实例
print(isinstance({‘1’:1,‘2’:2},dict)) >> True #字典实例
3. 迭代器
可以被next()函数调用,并不断返回下一个值的对象。
3.1 迭代
获取一个元素的过程叫迭代。
3.2 可迭代对象
包括字符串、列表、集合、元组等,以及生成器。用isinstance(a,Iterable)可判断对象a是否是可迭代的。
如:
from collections.abc import Iterable
print(isinstance([1,2],Iterable)) >> True
print(isinstance((1,2),Iterable)) >> True
print(isinstance({‘1’:1},Iterable)) >> True
print(isinstance(‘abc’,Iterable)) >> True
print(isinstance({1,2},Iterable)) >> True
注意:整数,浮点数,bool值等都是不可迭代的。
from collections.abc import Iterable
print(isinstance(123,Iterable)) >>False
print(isinstance(123.0,Iterable)) >>False
print(isinstance(True,Iterable)) >>False
注意:可迭代的对象不一定都是迭代器,但可以用iter()函数转换为迭代器。
如:
lst = [1,2,3,4]
print(next(lst)) >>TypeError: ‘list’ object is not an iterator
print(type(lst)) >> <class ‘list’> 是因为lst仅仅是一个列表对象。
但是,如果
lst = [1,2,3,4] #lst是个列表
lst = iter(lst) #将列表lst转化为迭代器
print(next(lst)) >>1