文章目录
一、列表生成器
列表生成器:如字面意思,列表生成器就是创建一个列表。
代码案例如下:
list_1 = [x for x in range(1,6)]
list_2 = [i*3 for i in range(1,6)]
# 可在生成前对列表输入值进行操作:如上 i*3
print(list_1)
print(list_2)
输出结果:
[1, 2, 3, 4, 5]
[3, 6, 9, 12, 15]
二、生成器、迭代器
1.什么是生成器和迭代器
迭代器:它是一个有状态的对象,或者可以说就是一个用来存储数据的容器,但是它并不是将一个序列一次性全部实例化存储,而是将这个序列的一种表达式放入内存中,在需要该序列中的某个元素时,利用next()方法调用该表达式从而返回所需的值,每次将返回下一个值。每次调用next()方法返回数列的下一个数,上一个值因为没有变量对象,被解释器释放,所以内存占用始终为常数。
生成器:生成器就是一种特殊的迭代器,所有生成器都是迭代器,但是迭代器不全是生成器。使用yield替换了return的函数,python解释器就将其视为一个generator(生成器),在每次next()或send()等类似方法调用该generator后,循环语句执行,当执行到含有yield的语句时,迭代结束,当开始下一次迭代时,代码从yield的下一条语句开始执行。
!!!!
注释:yield 的作用就是把一个函数变成一个 generator。
迭代器协议:迭代器内部必须同时拥有next()方法和iter()方法
2.创建生成器的两种方法
genera_1 = (i for i in range(1,6))
# 与列表生成器不同,由小括号包裹
print(genera_1) #打印迭代器地址
print(next(genera_1)) #第一次迭代(打印第一个元素)
print(next(genera_1)) #第二次迭代
print(next(genera_1)) #.....
print(genera_1.__next__()) #next()与__next__()效果相同,推荐使用前一个
print(genera_1.__next__())
print(genera_1.__next__()) #上述创建了一个包含了从1到5的五个元素的生成器,可描述为,该生成器可迭代5次,但此语句将迭代第六次,此时将报错
输出:
StopIteration #报错
<generator object <genexpr> at 0x0000025906E81F90>
1
2
3
4
5
def generat_1():
i = 0
while True:
print("开始")
i+=1
cout = yield 1 #yield替换return,但是没有返回 1!
print(cout)
print("第%d次迭代" % i)
g = generat_1()
next(g)
next(g)
next(g)
g.send("hahahaha") #.send()方法,在使得生成器开始迭代的同时,可以给yield赋值,此时可以定义一个变量接收。(在不给yield赋值时,将默认为None)。
g.send("jiuzhe?")
输出:
开始 #第一次next() (第一次迭代开始)
None #第二次next() (第二次迭代开始) 上一次迭代在遇到yield语句时已经结束。
第1次迭代
开始
None #第三次next() (第三次迭代开始)
第2次迭代
开始
hahahaha #(第四次迭代开始)
第3次迭代
开始
jiuzhe? #(第五次迭代开始)
第4次迭代
开始
三、生成器几点须知(next,send,iter(),for循环原理简单分析)
1.next()-------计算一个值
注意:生成器在创建的时候已经决定了
能计算出的值的个数,调用超过这个个数,
程序报错:StopIteration
2.send()------计算一个值,也可添加给yield一个值
具体见上述代码,以下为特别讲解
g.send(None) #等价于 next(g) g为一个迭代器对象
3.iter()-----生成一个 list_iterator 迭代器对象
foo = [3,4,5]
foo2 = [11,12,13]
G = foo.__iter__() #__iter__()等价于iter()
M = iter(foo2)
print(G)
print(M)
print(next(G))
print(next(G))
print(next(M))
print(next(M))
输出:
<list_iterator object at 0x000001830EFD9130> #两个 list_iterator 迭代器地址
<list_iterator object at 0x000001830EFD9100>
3
4
11
12
4.for循环内部执行原理
-
调用对象的 iter() 方法, 返回一个迭代器对象。
-
循环取值
-
判断迭代循环是否循环到最大次数, 即是否遇到报错:StopIteration, 是,则跳出迭代循环。
以下为2,3部分伪代码:
while:
try:
i = next(list_Iterator) #取值
except StopIteration: #错误捕捉
break
5.补充一个提取文件后,找出文件最长行方法
max(len(x.strip()) for x in open('<txt>','r'))