可迭代对象和迭代器
可迭代对象和迭代器
一、迭代器的概念
迭代器即迭代的工具,那什么是迭代呢?
迭代是一个重复的过程,每次重复即一次迭代,并且每次迭代的结果都是下一次迭代的初始值
while True: #只是单纯地重复,因而不是迭代
print('===>')
l=[1,2,3]
count=0
while count < len(l): #迭代
print(l[count])
count+=1
二、可迭代对象
python中一切皆对象,对于这一切的对象中,但凡有__iter__
方法的对象,都是可迭代对象。
基于上一次的结果推出下一次结果
#
# 可迭代(具有__iter__方法)对象
x = 2 # 不可迭代
# x.__iter__ # SyntaxError: invalid syntax
s = 'randysun'
s.__iter__() # str 为可迭代对象 <str_iterator object at 0x035B4D70>
lt = [1, 2, 3]
lt.__iter__() # list 为可迭代对象
dic = {'a': 1, "b": 2}
dic.__iter__() # dict 为可迭代对象
tup = (1,)
tup.__iter__() # tuple 为可迭代对象
se = {1, 2, 3}
se.__iter__() # 可迭代对象
f = open('test.py')
f.__iter__() # 可迭代对象
def func():
pass # 不可迭代对象
# 有__iter__()方法的对象都是可迭代对象,然后除了数字类型和函数之外都是可迭代对象
可迭代的对象:Python内置str、list、tuple、dict、set、file都是可迭代对象,除了数字类型外。
s = 'randysun'
s_iter = s.__iter__()
print(s_iter.__next__())
print(s_iter.__next__())
print(s_iter.__next__())
特点:内置有__iter__
方法的都叫可迭代的对象。(可以理解为可以for循环打印)
[
二、迭代器对象
只有字符串和列表、元组都是依赖索引取值的,而其他的可迭代对象都是无法依赖索引取值的。因此我们得找到一个方法能让其他的可迭代对象不依赖索引取值。
迭代器对象: 具有__iter__以及__next__方法的叫做迭代器对象,只有文件是迭代器对象
s = 'randy' # 可迭代对象,不属于迭代器对象
s.__iter__()
lt = [1, 2, 3] # 可迭代对象,不属于迭代器对象
dic = {'a': 1, 'b': 2} # 可迭代对象,不属于迭代器对象
tup = (1,) # 元组只有一个元素必须得加逗号# 可迭代对象,不属于迭代器对象
se = {1, 2, 3} # 可迭代对象,不属于迭代器对象
f = open('time.py') # 可迭代对象,迭代器对象
# 只有文件是迭代器对象
通过迭代对象和迭代器实现遍历列表
# 不依赖索引取值 for循环原理
lt = [1, 2, 3]
lt_iter = lt.__iter__()
while True:
try:
print(lt_iter.__next__())
except StopIteration:
break
1
2
3
for i in lt: # 可迭代对象;迭代器对象 不依赖索引取值,而是迭代取值
print(i)
# 1. 首先使用__iter__把lt变成迭代器对象,对文文件也要使用iter方法把文件再一次iter
# 2. 然后使用__next__方法进行迭代取值
# 3. 判断StopIteration异常,遇到异常终止
三、for循环原理
for循环称为迭代器循环,in后必须是可迭代的对象。
lis = [1, 2, 3]
for i in lis:
print(i)
1
2
3
因为迭代器使用__iter__
后还是迭代器本身,因此for循环不用考虑in后的对象是可迭代对象还是迭代器对象。
由于对可迭代对象使用__iter__
方法后变成一个迭代器对象,这个迭代器对象只是占用了一小块内存空间,他只有使用__next__
后才会吐出一个一个值。如lis = [1,2,3,4,5,...]
相当于一个一个鸡蛋,而lis = [1,2,3,4,5,...].__iter__
相当于一只老母鸡,如果你需要蛋,只需要__next__
即可。
Python2中
print(range(10)) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Python3中
print(range(10)) # range(0, 10)
四、总结
-
可迭代对象:具有__iter__方法的对象就是可迭代对象,除了数字类型和函数都是可迭代对象
-
可迭代器对象:具有__iter__和__next__方法的都是迭代器对象,只有文件
-
迭代器对象一定是可迭代对象,可迭代对象不一定是可迭代器对象
-
for循环 == 迭代循环
- 把lt(可迭代对象/迭代器对象)用__iter__方法转换成迭代器对象
- 使用__next__取出迭代器里的所有值
- 使用__next__方法取尽迭代器中的所有值,一定会报错,通过异常捕捉退出while循环
- 解决了不依赖索引取值
-
优缺点
-
优点:
- 提供一种统一的、不依赖于索引的迭代方式
- 惰性计算,节省内存
-
缺点:
- 无法获取长度(只有在next完毕才知道到底有几个值)
- 一次性的,只能往后走,不能往前退,取值麻烦,只能一个一个取,并且只能往后取,值取了就没了