迭代器
迭代协议
"""
什么是迭代协议。
迭代器是什么?
是访问集合类的一种方式,一般用来遍历数据。
for循环可以遍历数据
迭代器和以下标的访问方式不一样,迭代器是不能返回的(后退)
alist[0] alist[2] alist[1] 是不行的
[ ]下标访问 背后的原理/协议 是 __getitem__
迭代器提供了一种惰性访问数据的方式
__iter__
"""
from collections.abc import Iterable,Iterator
"""
Iterable:__iter__
Iterator:迭代器 继承Iterable, __iter__ __next__
"""
list
a = [1,2]
print(isinstance(a,Iterable))
print(isinstance(a,Iterator))
迭代器和可迭代对象区别
from collections.abc import Iterable,Iterator
a = [1,2]
print(isinstance(a,Iterable))
print(isinstance(a,Iterator))
iter_rator = iter(a)
print(isinstance(iter_rator,Iterable))
print(isinstance(iter_rator,Iterator))
"""
iter(传入一个可迭代对象)
返回一个迭代器
换一个说法
iter(传入一个实现__iter__的对象)
返回一个是实现了 __iter__ __next__的对象
"""
for循环与迭代
class Company(object):
def __init__(self, employee_list):
self.employee = employee_list
def __iter__(self):
yield 1
yield 2
yield 3
def __getitem__(self, item):
return self.employee[item]
if __name__ == "__main__":
company = Company(["tom", "bob", "jane"])
for i in company:
print(i)
"""
for循环 会去company 寻找__iter__协议,如果没有,退而求其次,选择 __getitem__
如果有iter,则会去选择__iter__
"""
自实现 迭代器
from collections.abc import Iterator
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
class Company(object):
"""
使用自己的迭代器类
"""
def __init__(self, employee_list):
self.employee = employee_list
def __iter__(self):
return MyIterator(self.employee)
if __name__ == "__main__":
company = Company(["tom", "bob", "jane"])
my_itor = iter(company)
for item in company:
print (item)
生成器
生成器函数
def gen_func():
yield 1
yield 2
yield 3
def func():
return 1
return 2
gen = gen_func()
res= func()
for i in gen:
print(i)
"""
生成器对象,python编译字节码的时候就产生了,它发现了yield
"""
"""
惰性求值,延迟求值提供了可能
斐波那契
0 1 1 2 3 5 8
"""
def fib(index):
"""
打印 斐波那契10位数
"""
if index <=2:
return 1
else:
return fib(index-1) +fib(index-2)
print(fib(10))
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))
def fib3(index):
n,a,b = 0,0,1
while n<index:
yield b
a,b=b,a+b
n+=1
for data in fib3(10):
print(data)
生成器如何读取大文件
"""
读取一个500G的文件
f=open()
for line in f: 按照行读
如果这个500G文件只有一行,特殊分隔符 {|}
f = open()
f.read(4096) # 只有读出4096个字符
f.read(4096)
"""
def myreadlines(f, newline):
"""
:param f: 文件句柄
:param newline:分隔符
"""
buf = ""
while True:
while newline in buf:
pos = buf.index(newline)
yield buf[:pos]
buf = buf[pos + len(newline):]
chunk = f.read(4096)
if not chunk:
yield buf
break
buf += chunk
with open("input.txt") as f:
for line in myreadlines(f, "{|}"):
print (line)