from collections.abc import Iterable, Iterator
a = [1, 2]
iter_rator = iter(a)
print(isinstance(a, Iterable))
print(isinstance(a, Iterator))
print(isinstance(iter_rator, Iterator))
输出结果
True
False
True
list只是可迭代,而不是一个迭代器。
这段代码能打印出结果,就是因为在Company内部自动生成了一个__iter__方法。
class Company(object):
def __init__(self, employee_list):
self.employee = employee_list
def __getitem__(self, item):
return self.employee[item]
if __name__ == "__main__":
company = Company(["tom", "bob", "jane"])
for item in company:
print (item)
输出结果
tom
bob
jane
下面模拟实现一个迭代器
from collections.abc import Iterator
class Company(object):
def __init__(self, employee_list):
self.employee = employee_list
def __iter__(self):
return MyIterator(self.employee)
class MyIterator(Iterator):
def __init__(self, employee_list):
self.iter_list = employee_list
self.index = 0
def __next__(self):
#真正返回迭代值的逻辑
try:
word = self.iter_list[self.index]
except IndexError:
raise StopIteration
self.index += 1
return word
if __name__ == "__main__":
company = Company(["tom", "bob", "jane"])
my_itor = iter(company)
while True:
try:
print(next(my_itor))
except StopIteration:
pass
输出结果
tom
bob
jane
只要函数里有yield,那么这个函数就是生成器函数。
yield和return的区别:
def gen_func():
yield 1
def func():
return 1
if __name__ == "__main__":
#生成器对象,在python编译字节码的时候就产生了
gen = gen_func()
print(gen)
re = func()
print(re)
输出结果
<generator object gen_func at 0x0000025AE4983048>
1
yield返回的是一个生成器,return返回的是返回值。
def gen_func():
yield 1
yield 2
yield 3
def func():
return 1
if __name__ == "__main__":
#生成器对象,在python编译字节码的时候就产生了
gen = gen_func()
for value in gen:
print(value)
输出结果
1
2
3
一个函数里不能在return后面再加一个return,但是可以有多个yield。return之后函数的调用就结束了,而yield调用之后还可以继续yield。
生成器函数为惰性求值,延迟求值提供了可能。下面来看看生成器函数的一个使用。
(1)斐波那契数列普通写法
def fib(index):
if index <= 2:
return 1
else:
return fib(index-1) + fib(index-2)
print(fib(10))
输出结果
55
(2)斐波那契数列列表写法
def fib2(index):
re_list = []
n, a, b = 0, 0, 1
while n < index:
re_list.append(b)
a, b = b, a+b
n += 1
return re_list
print(fib2(10))
输出结果
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
(3)斐波那契数列yield写法
def gen_fib(index):
n, a, b = 0, 0, 1
while n < index:
yield b
a, b = b, a+b
n += 1
for data in gen_fib(10):
print(data)
输出结果
1
1
2
3
5
8
13
21
34
55
yield可以把整个计算的过程展现出来,它只在计算的时候消耗内存,大大节省了内存。
input.txt文件内容
Prior to beginning tutoring sessions{|}, I ask new students to fill{|} out a brief self-assessment{|} where they rate their{|} understanding of various Python concepts. Some topics ("control flow with if/else" or "defining and using functions") are understood by a majority of students before ever beginning tutoring. There are a handful of topics, however, that almost all{|} students report having no knowledge or very limited understanding of. Of these
读取代码
def myreadlines(f, newline):
buf = "" #已经读出的数据
while True:
while newline in buf: #如果分隔符在buf中
pos = buf.index(newline) #分隔符的位置
yield buf[:pos] #返回一行内容
buf = buf[pos + len(newline) : ] #下一行开始往后的内容
chunk = f.read(4096) #一次读取4096个字符
if not chunk:
#说明已经读到了文件结尾
yield buf
break
buf += chunk
with open("input.txt") as f:
for line in myreadlines(f, "{|}"): #分隔符为{|}
print(line)
输出结果
Prior to beginning tutoring sessions
, I ask new students to fill
out a brief self-assessment
where they rate their
understanding of various Python concepts. Some topics ("control flow with if/else" or "defining and using functions") are understood by a majority of students before ever beginning tutoring. There are a handful of topics, however, that almost all
students report having no knowledge or very limited understanding of. Of these