迭代(Iteration),迭代器协议,迭代器(Iterator),可迭代对象(Iterable)
迭代(Iteration):用简单的话讲,它就是从某个地方(比如列表)取出一个元素的过程。当我们使用一个循环来遍历时,这个过程本身就叫迭代。
例如:
1
2
3
|
li = ['a','b','c','d']
for item in li:
print("迭代列表li:",item)
|
执行以上程序会输出如下结果:
1
2
3
|
li = ['a','b','c','d']
for item in li:
print("迭代列表li:",item)
|
迭代器协议:对象需要提供iter方法,它要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代。
迭代器(Iterator):任何对象,如果它的类有next 方法和iter方法,next方法返回下一个元素,iter方法返回迭代器自己本身。
可迭代对象(Iterable):实现了迭代器协议对象。list、tuple、set、dict都是Iterable(可迭代对象),但不是Iterator(迭代器对象)。但可以使用内建函数iter(),转换成Iterator(可迭代器对象)。
例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
l = ['a','b','c','d']
t = ('a','b','c','d')
s = {'a','b','c','d'}
d = {1:'a',2:'b',3:'c',4:'d'}
iter_l = iter(l) # 列表转换为Iterator
print(iter_l)
iter_t = iter(t) # 元组转换为Iterator
print(iter_t)
iter_s = iter(s) # 集合转换为Iterator
print(iter_s)
iter_d = iter(d) # 字典转换为Iterator
print(iter_d)
|
执行以上程序会输出如下结果:
1
2
3
4
|
<list_iterator object at 0x7f1ea443a8d0>
<tuple_iterator object at 0x7f1ea443a908>
<set_iterator object at 0x7f1ea4439bd0>
<dict_keyiterator object at 0x7f1ea4432bd8>
|
for item in Iterable循环的本质就是先通过iter()函数获取可迭代对象的迭代器,然后对获取到的迭代器不断调用next()方法来获取下一个值并将其赋值给item,当遇到StopIteration的异常后循环结束。
例如:
1
2
3
4
5
6
7
8
9
10
|
l = ['a','b','c','d']
iter_l = iter(l) #列表转换为Iterator
#迭代列表对象
for item in l:
print("迭代列表l:",item)
#迭代列表Iterator对象,和迭代列表是一样的。
for item in iter_l:
print("迭代列表Iterator iter_l:",item)
|
执行以上程序会输出如下结果:
1
2
3
4
5
6
7
8
|
迭代列表l: a
迭代列表l: b
迭代列表l: c
迭代列表l: d
迭代列表Iterator iter_l: a
迭代列表Iterator iter_l: b
迭代列表Iterator iter_l: c
迭代列表Iterator iter_l: d
|
除了使用for in语法,还可以调用迭代器的next()方法来迭代数据。
例如:
1
2
3
4
5
6
7
8
9
10
11
|
listArray=[1,2,3] # 定义一个list
iterName=iter(listArray) # 使用iter()函数
print(iterName) # 结果:是一个列表list的迭代器
<list_iterator object at 0x0000017B0D984278>
print(next(iterName)) # 结果:1
print(next(iterName)) # 结果:2
print(next(iterName)) # 结果:3
print(next(iterName)) #没有迭代到下一个元素,直接抛出异常
Traceback (most recent call last):
File "Test07.py", line 32, in <module>
StopIteration
|
列表的键值对迭代
Python内置的enumerate函数可以以键值对的形式迭代列表。
例如:
1
2
3
|
l = ['a','b','c','d']
for i, value in enumerate(l):
print("列表l的键值对迭代:",i,value)
|
执行以上程序会输出如下结果:
1
2
3
4
|
列表l的键值对迭代: 0 a
列表l的键值对迭代: 1 b
列表l的键值对迭代: 2 c
列表l的键值对迭代: 3 d
|
字典迭代
默认情况下,dict迭代的是key。如果要迭代value,可以用for value in d.values()
,如果要同时迭代key和value,可以用for k, v in d.items()
。
例如:
1
2
3
4
5
6
7
8
9
10
11
12
|
d = {1:'a',2:'b',3:'c',4:'d'}
#字典默认迭代 key迭代
for item in d:
print("迭代字典d的key:",item)
#字典键值迭代 value迭代
for item in d.values():
print("迭代字典d的value:",item)
#字典键值对迭代 value迭代
for item_key,item_value in d.items():
print("迭代字典d的键值对:",item_key,item_value)
|
执行以上程序会输出如下结果:
1
2
3
4
5
6
7
8
9
10
11
12
|
迭代字典d的key: 1
迭代字典d的key: 2
迭代字典d的key: 3
迭代字典d的key: 4
迭代字典d的value: a
迭代字典d的value: b
迭代字典d的value: c
迭代字典d的value: d
迭代字典d的键值对: 1 a
迭代字典d的键值对: 2 b
迭代字典d的键值对: 3 c
迭代字典d的键值对: 4 d
|
字节,字符串迭代
由于字节对象,字符串对象也是可迭代对象,因此,也可以作用于for循环:
例如:
1
2
3
4
5
6
|
s = "hello"
for item in s:
print("迭代字符串s:",item)
b = b"hello"
for item in b:
print("迭代字节b:",item)
|
执行以上程序会输出如下结果:
1
2
3
4
5
6
7
8
9
10
|
迭代字符串s: h
迭代字符串s: e
迭代字符串s: l
迭代字符串s: l
迭代字符串s: o
迭代字节b: 104
迭代字节b: 101
迭代字节b: 108
迭代字节b: 108
迭代字节b: 111
|
判断是否是可迭代对象
通过collections模块的Iterable类型判断是否是可迭代对象。Iterator类型判断是否是迭代器对象。
isinstance()函数判断对象是否是某类型的实例。返回值True代表是某类的实例,False代表不是某类的实例。
例如:
1
2
3
4
5
6
7
8
9
|
from collections import Iterable
from collections import Iterator
s = "hello"
b = b"hello"
print(isinstance(s, Iterable)) #字符串str是Iterable
print(isinstance(s, Iterator)) #字符串str不是Iterator
print(isinstance(b, Iterable)) #字节bytes是Iterable
print(isinstance(b, Iterator)) #字节bytes不是Iterator
|
执行以上程序会输出如下结果:
1
2
3
4
|
True
False
True
False
|
为什么list、dict、str,bytes等数据类型不是Iterator?
Iterator对象表示的是一个数据流,是有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。而list、dict、str,bytes等数据类型都实现了len()函数,知道其长度大小。所以不是Iterator对象。
转载请注明本网址。