iOS开发人员如何学习Python编程13-函数4
这是我参与11月更文挑战的13天,活动详情查看:2021最后一次更文挑战。
生成器(generator
)
列表所有数据都在内存中,如果有海量数据的话会非常消耗内存。
例如,我们仅仅需要访问前面几个元素,但后面绝大多元素占用的内存就会浪费了。\ 那么生成器就是在循环的过程中根据算法不断推算出后续的元素,这样就不用创建整个完整的列表,从而节省大量的空间。\ 总而言之,就是当我们想要使用庞大数据,又想让它占用的空间少,那就使用生成器。
如何创建生成器
生成器表达式
生成器表达式
来源于迭代和列表解析的组合,生成器和列表解析类似,但是它使用()
而不是[]
:
``` g = (x for x in range(5)) print(g) # generator object print(next(g)) print(next(g)) print(next(g)) print(next(g)) print(next(g))
超出报错
print(next(g))
for i in g: print(i) ```
生成器
当一个函数中包含yield
关键字,那么这个函数就不再是一个普通的函数,而是一个generator
。
生成器
表达式来源于迭代和列表解析的组合,生成器
和列表解析类似,但是它使用()
而不是[]
。
调用函数就是创建了一个生成器对象。其工作原理就是通过重复调用next()
或者__next__()
方法,直到捕获一个异常:
``` def yieldtest(number): n = 0 # li = [] while n<number: # li.append(n) yield n n+=1
res = yieldtest(20)
print(res) # generator object
print(next(res)) # 0
print(next(res)) # 1
print(next(res)) # 2
``
**⚠️注意:**
-
yield返回一个值,并且记住这个返回值的位置,下次遇到
next()调用时,代码从
yield的下一条语句开始执行。与
return的差别是,
return`也是返回一个值,但是直接结束函数。
例如,实现斐波那契数列。除第一个和第二个数外,任何一个数都可以由前两个相加得到:1,1,2,3,5,8,12,21,34.....
``` def createNums(): print("-----func start-----") a,b = 0,1 for i in range(5): # print(b) print("--1--") yield b print("--2--") a,b = b,a+b print("--3--") print("-----func end-----")
g = createNums()
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
```
send()
send()
和next()
一样,都能让生成器继续往下走一步(遇到yield
返回),但send()
能传一个值,这个值作为yield
表达式整体的结果:
```
def test():
a1 = yield "hello"
print("---1---")
yield a1
res = test()
print(next(res)) # "hello"
print(res.send("world")) # "world"
``
也就是说,通过
send方法可以强行修改上一个
yield`表达式值。
比如函数中有一个yield
赋值:
a1 = yield "hello"
1. 第一次迭代到这里会返回"hello"
,但是a1
还没进行赋值;
2. 第二次迭代时,使用.send("world")
;
3. 那么,就是相当于强行修改yield "hello"
表达式的值为"world"
;
4. 所以yield a1
结果为"world"
。