1.什么是迭代(iteration)和可迭代?
迭代:在Python中给定一个可迭代对象(如:列表,元组),通过for循环对其进行遍历,这种遍历操作即为迭代。
可迭代:可迭代是任何你可以用Python中的for循环遍历的东西。可迭代意味着可遍历,任何可以遍历的东西都是可迭代的。
2.常见的可迭代对象
序列是一种常见的可迭代类型,序列有一些特定的特征集,它们可以从0开始索引,以小于序列的长度结束,有一定的长度并且可以被切分。列表,元组,字符串等属于序列,都是可以迭代的。
但是不是所有可迭代的对象都是序列,如:集合,字典,文件,生成器等都是可迭代的,但它们不是序列。
如何判断哪些是可迭代的对象呢?可以通过导入collections模块的Iterable包中的isinstance()函数来判定。
>>> from collections import Iterable #模块载入
>>> a = 'abc'
>>> isinstance(a,Iterable) #判断字符串是否可迭代
True
>>> b = [1,2,3]
>>> isinstance(b,Iterable) #判断列表对象是否可迭代
True
>>> a = (1,2,3)
>>> isinstance(a,Iterable) #判断元组对象是否可迭代
True
>>>
3.Python中的for循环
不同于像c/c++之类语言的for循环,Python的for循环没有索引,而是依靠迭代器来进行循环。
c++的for循环:
int num[5] = {1,2,3,4,5}
for(int i=0; i<5; i++){
cout<<num[i]<<" ";
}
Python的for循环:
num = [1,2,3,4,5]
for n in num:
print(n)
在Python中,对于序列迭代类型可以用while循环进行手动索引遍历。
num = [1,2,3,4]
i = 0
while i < len(num):
print(num[i])
i += 1
但是,对于不是序列的对象,如字典,集合,文件等,这种手动索引的方式就行不通,因为它们不支持索引。
以下示例对一个集合进行while循环手动索引,会出现错误提示:
names = {'Jack','XiaoMing','LiBai','Alice'}
i = 0
while i < len(names):
print(names[i])
i += 1
Traceback (most recent call last):
File "test.py", line 4, in <module>
print(names[i])
TypeError: 'set' object does not support indexing
所以,我们不能使用索引手动对Python中的每一个迭代对象进行遍历,对于不是序列的迭代器来说,这是行不通的。
4.Python的for循环是迭代器驱动的
在Python中可以用内置的iter()函数来访问迭代器。
现在由三个可迭代对象,一个元组,一个集合,一个字符串
>>> num = {1,2,3,4}
>>> nums = (1,2,3,4)
>>> string = 'hi Jack'
用iter()函数访问,给iter()函数传递一个迭代器将返回一个迭代器给用户,不论迭代器是什么类型。
>>> iter(num)
<set_iterator object at 0x000001F3CEE21B40>
>>> iter(nums)
<tuple_iterator object at 0x000001F3CEE20B70>
>>> iter(string)
<str_iterator object at 0x000001F3CEE20BA8>
>>>
有了迭代器,就可以把迭代器传递给内置函数next()来获取它的下一项:
>>> num = [1,2,3]
>>> num_iterator = iter(num)
>>> next(num_iterator)
1
>>> next(num_iterator)
2
>>> next(num_iterator)
3
迭代器有其状态,一旦从中使用了一项即取出了一项,取出过的迭代器就消失了,当从迭代器中请求next()项时,如果其中没有了更多的项即请求超过了应有数量的项,会出现异常StopIteration:
>>> num = [1,2,3]
>>> num_iterator = iter(num)
>>> next(num_iterator)
1
>>> next(num_iterator)
2
>>> next(num_iterator)
3
>>> next(num_iterator)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>>
所以,我们可以从每次迭代中获得一个迭代器,迭代器唯一能做的就是用next()函数请求它们的下一项,如果没有了下一项,但你依然将它们传递给next(),那么就会引发StopIteration异常。
参考文章:https://linux.cn/article-9681-1.html