迭代和递归,最初在DNS resolution中见到过, 迭代指的A问B ,A问C,A问D . A向上一代一代的查问
下面进入本次文章的主题
python中的迭代和生成
为什么引入迭代:
迭代是数据处理的基石。扫描内存中放不下的数据集时,我们要找到一种惰性获取数据项的方式,
即按需一次获取一个数据项。这就是迭代器模式(Iterator pattern)。
可迭代的判断: 1.用命令 isinstance([], Iterable)
2. 如果这个对象中有__next__()方法,这个对象就是可迭代对象
注意: 字符串str,列表list,元组tuple,字典dic,集合set,文件对象 都不是可迭代对象.都没__next__方法
在for循环,就是使用__iter__方法,将其变成了可迭代对象
list1 = [1,2,3,4]
iter_l = l.__iter__()
print(iter_l.__next__()
//////////////生成器 generator
生成器的作用: 自动实现了生成器协议,不用再调用 __iter__()方法 再去生成可迭代对象了.
生成器 generator.创建方法: 一 二
创建生成器法一 : 用 ()
生成器也是可迭代对象,所以也能使用for循环啦
g = (x*x for x in range(10))
for a in g: (原理 调用的next方法,不断的去next
print(a)
创建生成器法二: 关键字 yield
· yield 是一个类似 return 的关键字,只是这个函数返回的是个生成器
· 当你调用这个函数的时候,函数内部的代码不立刻执行 ,而是返回一个生成器对象
· 当使用for进行迭代的时候,函数中的代码才会执行
def createGenerator():
for i in range(3):
yield i * i
myGenerator = createGenerator() #得到一个生成器对象
for i in myGenerator:
print(i)
第二个例子(多理解):
def foo():
print("starting...")
while True:
res = yield 4
print("res:",res)
g = foo()
return_val = next(g)
print(return_val)
print("*"*20)
print(next(g))
程序执行情况:
starting...
4
********************
res: None
4
1. g = foo()程序开始执行 : 因为foo函数中有yield关键字,所以foo函数并不会真的执行,而是先得到一个生成器g(相当于一个对象)
2. print(return_val) 调用next方法,foo函数开始执行,先执行foo函数中的print方法,然后进入while循环
遇到yield关键字,然后把yield想象成return,return了一个4之后,程序停止,没有执行赋值给res操作,此时next(g)语句执行完成,所以输出的前两行(第一个是while上面的print的结果,第二个是return出的结果)是执行print(next(g))的结果,
4.程序执行print("*"*20),输出20个*
5.执行第二个print(next(g)),这个时候和上面那个差不多,不过不同的是,这个时候是从刚才那个next程序停止的地方开始执行的,也就是要执行res的赋值操作,res = yield 4 这时候要注意,这个时候赋值操作的右边是没有值的(因为刚才那个是return出去了,并没有给赋值操作的左边传参数),所以这个时候res赋值是None,所以接着下面的输出就是res:None,
6.程序会继续在while里执行,又一次碰到yield,这个时候同样return 出4,然后程序停止,print函数输出的4就是这次return出的4.
关键问题 y = yield 8 怎么输出? 取决于send 和next
The value of the yield expression after resuming depends on the method which resumed the execution. If __next__() (or .next()) is used then the result is None. Otherwise, if send() is used, then the result will be the value passed in to that method.
yield 继续加码 关于send
send作用:1\传值给yield \2\和.__next__()一样的功能
def test():
i = 1
while i < 5:
temp = yield i**2
cc = 3
print(temp)
i += 1
t = test()
a = t.__next__()
print(a)
t.send('hello world')
输出内容:
1
hello world (这是 print(temp)的结果)
分析: 1.执行yield i**2 返回给变量a 所以打印1
2. t.send('hello world') 将yield后面的值变成'hello world, 然后是第二个next, 则temp = 'hello world ……..''