生成器和迭代器
笔记整理自:
https://www.liaoxuefeng.com/wiki/1016959663602400/1017318207388128
生成器
不需要占用很大内存,可以一边循环一边计算
把列表生成式的[]换成(),可以用next()获得generator下一个返回值
>>> g = (x * x for x in range(10)) >>> g <generator object <genexpr> at 0x1022ef630> >>> next(g) 0 >>> next(g) 1
但是用next调用到最后一个之后,后面的元素会报错(StopIteration),可以用for循环来迭代
>>> g = (x * x for x in range(10)) >>> for n in g: ... print(n)
如果一个函数包含yield关键字,那么这个函数就不再是一个普通函数,而是generator
generator和函数的执行流程不同,调用next()执行,遇到yield返回,再次执行时从上次返回的yield语句处继续执行def odd(): print('step 1') yield 1 print('step 2') yield(3) print('step 3') yield(5) >>> o = odd() >>> next(o) step 1 1 >>> next(o) step 2 3
同样也可以直接用for循环来迭代,但是用for循环调用generator时,发现拿不到generator的return语句的返回值。如果想要拿到返回值,必须捕获StopIteration错误,返回值包含在StopIteration的value中。
leetcode第118题:杨辉三角
class Solution:
def generate(self, numRows: int):
def yh(numRows):
result = [[1], [1, 1]]
n = 2
while n<numRows:
yield result
L = result[len(result)-1][:]
for i in range(1, len(L)):
L[i] = result[len(result)-1][i-1]+result[len(result)-1][i]
L.append(1)
result.append(L)
n += 1
if numRows == 0:
return []
elif numRows == 1:
return [[1]]
elif numRows == 2:
return [[1], [1, 1]]
else:
yh_array = []
for array in yh(numRows):
yh_array = array
return yh_array
s = Solution()
print(s.generate(2))
迭代器
可以直接作用于for循环的对象统称为可迭代对象,可以用 isinstance()判断一个对象是否是Iterable对象
>>> isinstance((x for x in range(10)), Iterable)
True
可以被next()调用并返回下一个值的对象称为迭代器:Iterator, 同样可以使用isInstance()来判断
list, dict, str虽然是Iterable但不是Iterator,可以用iter()函数变成Iterator
>>> isinstance(iter([]), Iterator)
True