一、可迭代对象与迭代器
1. 概念
-
迭代
迭代是指依次访问序列中的每个一元素,也称为遍历。 -
可迭代对象-Iterable
Iterable简单理解就是可以迭代的对象,主要有str,list,tuple,dict、set、generator等 -
迭代器
可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator
2、通过for循环来迭代Iterable对象
- 迭代字符串str
l = 'hello,python'
for e in l:
print(e,end='')
输出:
hello,python
- 迭代列表list
l = [1, 2, 3, 4, 5, 6]
for e in l:
print(e, end=' ')
- 迭代字典dict
字典默认迭代的是key值
d = {'1': 'mike', '2': 'john', '3': 3}
for key in d:
print(key)
【注】如果需要迭代value值的话可以使用d.values()生成一个Iterable,也可以通过d.items()同时迭代key,value
- 如果在迭代的时候想得到元素的索引,则可以使用enumerate()函数
l = 'hello,python'
for i,e in enumerate(l):
print(i,e,sep=':',end=' ')
输出:
0:h 1:e 2:l 3:l 4:o 5:, 6:p 7:y 8:t 9:h 10:o 11:n
3、常见的返回Iterable对象的函数
- 生成序列函数range()
- 字典的keys()、values()、items()函数
4、迭代器-Iterator
-
迭代Iterator对象与Iterable对象都是通过for…in…来访问每一个元素的
-
还可以通过python内置的next()函数访问元素,但是如果一直访问到了最后一个元素仍然调用next()函数则会抛出stopIteration异常。如:
it = iter(['hello,world'])
print(next(it))
print(next(it))
输出:
hello,world
print(next(it))
StopIteration
- Iterable可以转换成Iterator可以通过Python内置的iter()函数将Iterable类型转换成Iterator类型,如:
d = {'1': 'mike', '2': 'john', '3': 3}
key = d.keys()
print(isinstance(key,Iterable))
print(isinstance(iter(key),Iterator))
输出:
True
True
二、生成器-generator
如果元素序列可以按照某种算法推算出来,那我们可以在循环的过程中不断推算出后续的元素,这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator
1、通过类似于列表生成式的for循环创建列表生成器
g=(x for x in range(10) if x%2) # 注意此处是小括号
2、生成器可以通过for循环访问也可以通过next()函数访问
it = (x for x in range(3))
print(next(it))
for x in it:
print(x)
3、通过定义函数,使用yield关键字创建复杂的生成器
例如:创建一个产生斐波拉契数列的生成器
def fib(n):
if n < 0:
return None
count, a, b = 0, 0, 1
while count < n:
yield b
a, b = b, a + b
count = count + 1
return None
for x in fib(10):
print(x,end=' ')
输出:
1 1 2 3 5 8 13 21 34 55
4、生成器既是迭代器Iterator也是可迭代对象Iterable
例如:
g = (x for x in range(3))
print(type(g))
print(isinstance(g,Iterator))
print(isinstance(g,Iterable))
输出
<class 'generator'>
True
True
三、Iterable、Iterator、generator总结
-
首先,generator用于生成元素序列,既是一种Iterator,也是Iterable
-
Iterable有6种常见的类型:str,list,tuple,set,dict,generator
-
Iterator对象表示的是一个数据流,可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算.Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。
-
迭代器Iterator是一个可以记住遍历的位置的对象。如:
g = iter([x for x in range(3)])
print(next(g))
for x in g:
print(x)
输出0 1 2 而不是0 0 1 2
0 1 2
其通过next访问之后记住下次访问的位置是1,而不从重新从头开始访问