生成器
生成器 就是 自定义的迭代器
关键字yield
函数里面有了yield关键字之后,函数调用之前还是函数,函数调用之后就变成了生成器
def index(): print('first') yield 123, 234, 345 print('second') yield 'aaaa' print('third') yield 'xxxx' res = index() # 一旦调用就变成了生成器,可以用__next__() 取值 print(res.__next__()) print(next(res)) print(next(res)) # 上面3个是等价的,next() 等价于 .__next__ # 以下是输出结果 # first # (123, 234, 345) # second # aaaa # third # xxxx
用生成器实现range功能
range的功能
1 range(10) # 0-9
2 range(1,10) #1-9
3 range(1,10,2) # 1,3,5,7,9
如果用生成器来实现
def my_range(start, end=None, step=1): if not end: end = start start = 0 while start < end: yield start start += step res = my_range(10) for i in res: print(i)
生成器 的 关键字 yield 的传值
可以用 send 来传值
def index(name): print('%s 准备干饭' % name) while True: food = yield None # 默认是None,可以用sed来传值进去 print('%s吃%s' % (name, food)) res = index('Damon') res.__next__() res.send('苹果') res.send('橘子') res.send('西瓜')
输出的结果是
Damon 准备干饭
Damon吃苹果
Damon吃橘子
Damon吃西瓜
yield 和 return 的对比
yield: 1,函数中如果有yield,就变成了生成器
2,yield也可以有返回值,并且支出返回多个数据(以元祖的形式)
3,遇到yield函数的生成器,运行时指针会 停在 yield 后面,下一次调用的时候再移动
4,yield 也支持传值
return 1,后面跟返回值,也支持多个元素(以元祖的形式)
2,函数遇到return ,会直接停止
生成器练习题(面试)
def add(n, i): return n + i def test(): for i in range(4): yield i # 生成器返回值是0,1,2,3 g = test() for n in [1, 10, 20]: # 注意,这里列表是3个值 g = (add(n, i) for i in g) # 左右两边是括号,这是个生成器表达式 ''' 分三步 n = 1 和 n = 10 和 n = 30 ,i = 0,1,2,3 第一步 n = 1 g = (add(1 ,i) for i in g) # 但是并不会执行,三层循环执行完之后才会 #如果只有1次循环,list的输出的结果是[1,2,3,4] 第二部 n = 10 此时g已经重新赋值 g = (add(10, i) for i in (add(10, i) for i in g)) 如果结束,那list的 输出结果是[20,21,22,23],但是要循环3次,并不会执行 第三部 n = 20 此时g已经重新赋值 g = (add(20, i) for i in (add(20, i) for i in (add(20, i) for i in g))) 第三次执行完成之后,才会执行,此时需要套入的数据 n = 20 ,list(i)= 0,1,2,3 一次性执行完成,
相当于前面 n 的数值没有任何用处,要以最后一个n的赋值为准 ''' print(list(g)) # [60, 61, 62, 63]
其他常用参数
# abs 是求绝对值 print(abs(123)) print(abs(-123)) l = [1, 2, 3, 4, 5, 6, 7, 0] print(all(l)) # all 列表中的每一个元素,必须是真,结果是False print(any(l)) # any 列表中只要有一个元素是真,那就是真 Ture print(sum(l)) # sum 是求和 # divmod 商 和 余数 的 元祖。主要用于网页分页的效果 print(divmod(100, 10)) # (10,0) print(divmod(101, 10)) # (10,1) print(divmod(99, 10)) # (9,9) num, mod = divmod(100, 10) if not mod: page = num + 1 string = """ # hahahahh print('hello world') """ eval(string) # 执行‘’内部的代码 exec(string) # 执行‘’内部的代码 a = 123 s = 'aaaa' print(isinstance(s, str)) # 判断某个数据是不是某个实例 print(chr(68)) # 68指的是ASKII中的位置 print(ord('A')) # 返回ASKII中的序号 print(pow(2, 3)) # 2的3次方 print(pow(3, 3)) # 3的3平方 # round 是五舍六入 print(round(4.3)) print(round(4.5)) # 4 print(round(4.8)) # 5 s = 'aaa' print(s.encode('utf8')) # 转换成2进制 res = bytes(s, 'utf8') print(res) print(res.decode('utf8')) # 2进制解码,成UTF-8 print(str(res, 'utf8'))