最近进度有点放缓,字典应用之后遭遇Linux,捣鼓好几天,500页的书硬
着头皮翻了200页,挺有意思的内容:装虚拟机,运行Linux命令行,但是
超多的命令要一个个去练手要花费大量时间,想想还是不能一条路走到黑。
于是继续切换进程到Python。今天要写的是关于生成器。
网上很多教程,就不做搬运工了。直接讲一下我的理解:
关于生成器generator,从字面上理解,就是能生成***的机器,的确它是一个很牛逼的机器,他可以生成很多我们需要的数据,比如全体自然数,好好想一下,能用哪个表达式表示全体自然数么?如果真的能,运行一下内存会不会直接爆掉?所以,生成器的牛逼之处,就在于此,可以生产很多数据,而且不会爆表。怎么做到的?用啥直接生产,当然要按顺序,为什么没爆,因为用完啥就销毁了。
那迭代器iteraor又是啥?生产器generator都是特殊的、优雅的迭代器,反之则不成立。迭代器只能称其为一个带状态的对象、可以通过next()方法调用下一个值。
然后是否可迭代、是否迭代器,这两个概念,迭代器肯定是可迭代的,可迭代的不一定是迭代器,比如字符串可迭代,但是要使用iter()方法才能变成迭代器。
先来一个著名的斐波拉契数列(Fibonacci),除第一个和第二个数外,任意一个数都可由前两个数相加得到
# !/usr/bin/env python3.6
# -*- coding: utf-8 -*-
#__author__: Ed Frey
#date: 2018/8/10
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
#这个地方如果分行写,就不是简单的写成a=b,b=a+b了。
# 写一行的运算,其实是从右侧算起,2个式子算完,再赋值给左侧变量a,b
n = n + 1
f=fib(10)
for i in f:
print(i)
再来一个杨辉三角:
# !/usr/bin/env python3.6
# -*- coding: utf-8 -*-
#__author__: Ed Frey
#date: 2018/8/10
def yang(max):
L = [1]
n = 0
while L < max:
yield L
a = [1]+[L[i]+L[i+1] for i in range(n)]+[1]
n = n+1
b=yang(10)
for i in b:
print(i)
生成器,迭代器网上很多教程,就不在文章赘述了。最后再来
一个我现在还很懵逼的代码:
def add(s, x):
return s + x
def gen():
for i in range(4):
yield i
base = gen()
for n in [1, 10]:
base = (add(i, n) for i in base)
print(list(base))
核心语句是
# base = gen()
# for n in [1, 10]:
# base = (add(i, n) for i in base)
其实也就相当于
base = gen()
n = 1
base = (add(k, n) for k in base)
n = 10
base = (add(k, n) for k in base)
for循环产生了两次生成器表达式。然后...在打印list的时候
才开始执行生成器,2个表达式绑定的是n而不是一个1一个10(
变量n被赋值成了10,然后两个表达式都用10来计算)。
然后再一级级流通起来。如下图
第一次生成器表达式的执行过程: base = (10 + 0, 10 + 1, 10 + 2, 10 +3) 第二次,base = (10 + 10, 11 + 10, 12 + 10, 13 + 10) 结果[20, 21, 22, 23]