什么是迭代
1 迭代器
通常我们认为的迭代是能够循环的,如字符串,列表,元组等,这些数据类型都是根据自身的索引值进行循环的。
实际上,我们也是需要对字典、集合、文件等内容进行循环读取其内容的,这些数据类型本身是无序的,也就是没有索引值,索引我们要对这些内容进行读取的时候就用到了迭代器。
1.1 可迭代对象
可迭代的对象本身内置的__iter__()函数可以判断是否是可迭代对象
例如:
d={'a': 1, 'b': 2}
>>> d.__iter__()
<dict_keyiterator object at 0x0000000002220138>
可迭代的对象都内置了.iter()方法,等同于iter(d). 函数的参数是可迭代的对象
1.2 迭代器
i=iter(d)
i= d.iter() 可迭代对象的返回值赋值给一个值就是迭代器
思路:
要想明白可迭代器要先明白可迭代对象,可迭代对象的返回值赋值给另一值,这个值就是迭代器。
可迭代器的执行通过d.next()就可以循环取出可迭代对象的内容。在这里只是一个例子,等同于next(d)
1.2.1 white循环
d={'a': 1, 'b': 2}
i = l.__iter__() # i = iter(l)
while True:
try:
# print(next(i))
print(i.__next__()) # next(i)
except StopIteration: # 异常处理 结束信号
break
1.2.2 for 循环###
d = {'a': 1, 'b': 2}
for i in d: # for z直接迭代其对象
print(i)
for循环实现的本质
d = {'a': 1, 'b': 2}
i = iter(d)
for item in i: # 这里for循环直接迭代的是迭代器,说明迭代器也是可迭代对象
# try:
print(item) # for不用处理异常信息
# except StopIteration:
# break
下面的更明确:
d = {'a': 1, 'b': 2}
for item in iter(d): # 这里是for循环封装了iter()方法
# try:
print(item) # for不用处理异常信息
# except StopIteration:
# break
-
需要注意的是迭代器是只能从前往后取,但是迭代器是不清楚长度的,只能取到不能取为止,最后返回异常就全部取完了
-
迭代器构造了一种不依赖索引,但是能取值的统一的方法
1.2.3 文件的迭代
文件本身就是迭代器
with open("a.txt") as f: # f本身就是迭代器
f.__next__
f.__iter__
print(f)
print(f.__iter__())
for line in f:
print(line.strip())
下面是打印的:
print(f) print(f.iter()) 是一样的, f本身就是迭代器
_io.TextIOWrapper name='a.txt' mode='r' encoding='cp936'
_io.TextIOWrapper name='a.txt' mode='r' encoding='cp936'
为什么用迭代器:
优点:
1.迭代器提供了一种不依赖索引取值的方式
2. 迭代器与列表比较
迭代器取的是一个地址,迭代器是惰性计算,节省内存
列表会把所有的值读取到内存
缺点:
1.无法获取迭代器的长度,只有next到最后的地址报错后才知道
2.迭代器是一次性的,只能往后取值,直到next走完
1.2.4 查看可迭代对象与迭代器对象
判断是可迭代对象
from collections import Iterable,Iterator
s = "123"
l = [1,2,3]
t = (1,2,3)
d = {"a":1}
set1 = {1,2,3}
f = open("a.txt")
s.__iter__()
l.__iter__()
t.__iter__()
d.__iter__()
set1.__iter__()
f.__iter__()
print(isinstance(s,Iterable))
print(isinstance(l,Iterable))
print(isinstance(d,Iterable))
print(isinstance(set1,Iterable))
print(isinstance(f,Iterable))
结果:
True
True
True
True
True
只要内置了__iter__()方法,就是可迭代对象
判断迭代器对象
print(isinstance(s,Iterator))
print(isinstance(l,Iterator))
print(isinstance(d,Iterator))
print(isinstance(set1,Iterator))
print(isinstance(f,Iterator))
结果:
False
False
False
False
True
这里面只有文件是迭代器对象