迭代器

生成器,迭代器,可迭代对象,序列

1. 序列

  • 序列是有固定特征集的可迭代对象。它们可以从0开始索引,并以序列长度减1的值结束,它们有长度,可以分割

序列是一种很常见的可迭代对象。列表,元组和字符串都是序列。

2. 可迭代对象

可迭代对象是任何可以用for循环遍历的东西。可迭代对象可以被for循环遍历,任何可以被for循环遍历的东西都是可迭代对象。

Python中的很多东西都是可迭代对象,但并非所有的可迭代对象都是序列。集合,字典,文件和生成器都是可迭代对象,但这些都不是序列

3. 生成器

生成器也是迭代器,这意味着你可以在生成器上调用next函数来获取它的下一个元素:
生成器是可迭代对象

下面的代码是生成器的使用:

s=(x**2 for x in [1,2,3])# 这里是(),得到生成器
print s
print next(s)
print next(s)
print next(s)
# print next(s)

输出结果:

<generator object <genexpr> at 0x10e1c2aa0>
1
4
9

若去掉上述代码最后一行的注释,再打印print next(s)时,则抛出错误:

<generator object <genexpr> at 0x105981aa0>
Traceback (most recent call last):
1
4
9
  File "/Users/ycsun/PycharmProjects/ptest/main.py", line 7, in <module>
    print next(s)
StopIteration

如下,则返回一个列表:

s=[x**2 for x in [1,2,3]]
print s

结果:

[1, 4, 9]

4. 迭代器

迭代器驱动for循环

  • 迭代器驱动可迭代对象。你可以从任何可迭代对象中获得一个迭代器。你可以使用迭代器手动循环遍历可迭代对象。
  • 我们可以使用Python的内置iter函数向每个可迭代对象要一个迭代器。将一个可迭代对象传递给iter函数就返回一个迭代器,无论我们操作什么类型的可迭代对象。
  • 一旦我们有了迭代器,我们就可以用内置的next函数来获取它的下一个元素。
  • 迭代器是有状态的,这意味着一旦你使用了一个元素,它就消失了。

如果你想从迭代器请求next元素,但已经没有更多元素了,就会发生StopIteration异常:

  • 所以你可以从每个可迭代对象中获得一个迭代器。迭代器唯一能做的事情就是使用next函数获取它的下一个元素。如果使用next函数但是没有下一个元素,则会抛出StopIteration异常。
  • 因为迭代器也是可迭代对象,所以你可以使用内置的iter函数从迭代器中获取迭代器:
  • 当在可迭代对象上调用iter函数时,会返回迭代器。
  • 迭代器是可迭代对象,所有迭代器都是它们自己的迭代器。

s=[1,2,3,4,5]
l1=iter(s)
l2=iter(l1)

print l1
print l2

输出结果:


<listiterator object at 0x10872efd0>
<listiterator object at 0x10872efd0>

链接如下:

[](https://mp.weixin.qq.com/s/LP82EybDB6EN9hPauCSdGQ)

构造器

tuple()

s=(x**2 for x in [1,2,3])#生成器
print s
print tuple(s)# 将生成器传给构造器,输出(1,4,9)
print sum(s)#0

结果如下:

<generator object <genexpr> at 0x1050fbaa0>
(1, 4, 9)
0
  • 第二次使用生成器,sum(s)为0,因为生成器只能用一次就消失了。

解包

``
s={'k1':2,'k2':543}
x,y=s
print x,y

得到的是键,

k2 k1


## for 循环

> python 没有传统意义的带索引的for循环,而是底层用的生成器

+ Python的for循环不使用索引
+ 迭代器驱动for循环
+ 所以我们已经看到Python的for循环在底层不使用索引。Python的for循环使用迭代器。
+ 迭代器驱动可迭代对象。你可以从任何可迭代对象中获得一个迭代器。你可以使用迭代器手动循环遍历可迭代对象。


   > 我们来看看它是如何工作的。
   
+ 我们可以使用Python的内置iter函数向每个可迭代对象要一个迭代器。将一个可迭代对象传递给iter函数就返回一个迭代器,无论我们操作什么类型的可迭代对象。

下面是三个可迭代对象:

s={1,2,3,4,5}
m=(4,5,6)
n='hello,world'
print iter(s)
print iter(m)
print iter(n)


输出结果:

<setiterator object at 0x10d36ba50>
<tupleiterator object at 0x10d3f6fd0>
<iterator object at 0x10d3f6fd0>

+ 一旦我们有了迭代器,我们就可以用内置的next函数来获取它的下一个元素。

### 迭代器协议

+ Python中所有形式的迭代都是由迭代器协议驱动的。
+ 
可迭代对象可以被传递给iter函数以获取它们的迭代器。
迭代器:
+ 可以传递给next函数,返回下一个元素,如果没有更多元素,抛出StopIteration异常
+ 可以传递给iter函数并返回自身

这些语句反过来也是正确的::
    
    
+ 任何可以在不引发TypeError异常的情况下传递给iter函数的东西都是可迭代对象
+   任何可以在不引发TypeError异常的情况下传递给next函数的东西都是一个迭代器
+     任何可以传递给iter函数且返回自身的东西都是迭代器

>
这就是Python中的迭代器协议。
posted @ 2018-07-29 20:50  moonok  阅读(116)  评论(0编辑  收藏  举报