6.可迭代对象与迭代器
字面意思分析:可以重复的迭代的实实在在的东西。
list,dict(keys(),values(),items()),tuple,str,set,range, 文件句柄(待定)
专业角度: 内部含有'__iter__'
方法的对象,就是可迭代对象。
内置函数:dir()
print(dir(str))
dir:会把一个数据类型所含有的所有方法放在以字符串的方式存在一个列表里面。
判断一个对象是否是可迭代对象:
print(`__iter__`in dir(str))True
l1 = [1,2,3]
print(dir(s1))
print(dir((l1)))
print('__iter__' in dir(s1))
print('__iter__' in dir(range(10)))True
s1 = 'alex'
i = 100
print('__iter__' in dir(i)) # False
print('__iter__' in dir(s1)) # True
优点:
- 直观
- 操作方法较多
缺点:
- 占用内存
- 不能迭代取值(索引,字典的key)
迭代器:
字面意思:可以重复迭代的工具。
专业角度: 内部含有'__iter__'
并且含有"__next__"
方法的对象,就是迭代器
可以判断是否是迭代器:'__iter__'
and '__next__'
在不在dir(对象)
判断一个对象是否是迭代器
with open('文件1',encoding='utf-8',mode='w') as f1:
print(('__iter__' in dir(f1)) and ('__next__' in dir(f1)))
可迭代对象转化成迭代器:
l1 = [1, 2, 3, 4, 5]
# 内置函数iter()
obj = iter(l1)
迭代器可以迭代取值。利用next()进行取值
iter([1,2,3])[1,2,3].___iter__()
l1 = [1, 2, 3, 4, 5]
# 内置函数iter()
obj = iter(l1)
# print(obj)
print(next(obj))# print(obj.__next__())
print(next(obj))# print(obj.__next__())
print(next(obj))# print(obj.__next__())
print(next(obj))# print(obj.__next__())
print(next(obj))# print(obj.__next__())
一次只取一个值,多取就会报错
迭代器优点:
- 非常节省内存
- 惰性机制,next一次,取一个值。
迭代器缺点:
- 不直观,不走回头路
- 操作不灵活
- 效率相对低。
特性:
l1 = [22, 33, 44, 55, 66, 77]
obj = iter(l1)
for i in range(3):
print(next(obj))
for i in range(2):
print(next(obj))
'''
22
33
44
55
66
'''
利用while 循环取值
利用while循环,模拟for循环内部循环可迭代对象的机制。
- 先要将可迭代对象转化成迭代器。
- 利用next对迭代器进行取值。
- 利用异常处理try一下防止报错。
try:
l1 = [1,]
# l1[::2]
l1[100]
# IndexError
except IndexError:
pass
s = 'gkffdsa;lfkdsk;lafkds;laldgjfd'
obj = iter(s)
while 1:
try:
print(next(obj))
except StopIteration:
break
18.2 可迭代对象与迭代器的对比
可迭代对象:是一个私有的方法比较多,操作灵活(比如列表,字典的增删改查,字符串的常用操作方法等),比较直观,但是占用内存,而且不能直接通过循环迭代取值的这么一个数据集。
当你侧重于对于数据可以灵活处理,并且内存空间足够,将数据集设置为可迭代对象是明确的选择。
迭代器: 是一个非常节省内存,可以记录取值位置,可以直接通过循环+next方法取值,但是不直观,操作方法比较单一的数据集。
当你的数据量过大,大到足以撑爆你的内存或者你以节省内存为首选因素时,将数据集设置为迭代器是一个不错的选择。(可参考为什么python把文件句柄设置成迭代器)。