iOS开发人员如何学习Python编程13-函数4

语言: CN / TW / HK

这是我参与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"