python3中的range返回的是迭代器吗?


本文摘自php中文网,作者爱喝马黛茶的安东尼,侵删。

Pyhton3的range是返回的什么?很多人都会不假思索的说,这还不简单,在Python2中range()会返回list,到了Python3range已经使用xrange替换,返回的是一个迭代器(Iterator)。

恭喜你,答错了。

PYTHON1.jpg

range()返回的是一个Iterable,并不是一个Iterator.

1

2

3

4

5

6

7

8

9

10

11

a  Python 3.6.3 (default, Nov  3 2017, 14:41:25)

Type 'copyright', 'credits' or 'license' for more information

IPython 6.2.1 -- An enhanced Interactive Python. Type '?' for help.

In [1]: a = range(10)

In [2]: a

Out[2]: range(0, 10)

In [3]: import collections

In [4]: isinstance(a, collections.Iterable)

Out[4]: True

In [5]: isinstance(a, collections.Iterator)

Out[5]: False

原理很简单,先简单说一下Iterable和Iterator,不要试图比较二者有什么不同,因为二者根本就是不同的概念。二者字面意思都非常明确:Iterable就是一个可迭代的对象,对其调用iter(Iterable)将会得到一个迭代器;而Iterator就是一个迭代器,对其调用next(Iterator)将会得到下一个元素。

Python推崇协议,说白了就是鸭子类型。你如果实现了__iter__(),(即对你调用iter()可以得到一个Iterator)那你就是一个Iterable;如果实现了__next__()和__iter__()就是一个Iterator。

等等,Iterator不就是调用next()得到下一个元素就可以了?为什么Iterator也要实现Iterable的__iter__()方法,这不纯粹啊!

为什么Python的Iterator要实现__iter__()呢(通常的实现都是return self)。官方文档中说的相当清楚。

1

Iterators are required to have an __iter__() method that returns the iterator object itself so every iterator is also iterable and may be used in most places where other iterables are accepted.

简单翻译一下,就是说Iterator也要求实现__iter__(),因为很多地方接收的参数是一个Iterable,如果所有的Iterator都是Iterable,那么这些用Iterable地方都可以无障碍地使用Iterator了。比如说for循环吧,关于for循环,我在Python的wiki中(已经比较老了)找到这样的描述:

1

Basically, any object with an iterable method can be used in a for loop. Even strings, despite not having an iterable method – but we’ll not get on to that here.

即,for循环拿到一个Iterable的Iterator,然后使用这个Iterator进行迭代。如果Iterator实现了__iter__()方法,那么for循环就可以无障碍地对Iterator进行迭代了,Neat!想象一下,Python的生成器也是Iterator,如果for循环不能支持对Iterator迭代,生不如死啊。

所以对Iterator就有了这样一个“过分”的要求。我们可以认为,所有的Iterator都是Iterable。那么回到最初的问题,为什么range()反回的是一个Iterable而不是Iterator呢?

考虑我们平时使用range(),我们认为这是一个表示范围的一个容器。可以使用这个容器去初始化成别的容器,这没有任何问题。

1

2

3

4

5

>>> numbers = range(3)

>>> tuple(numbers)

(0, 1, 2)

>>> tuple(numbers)

(0, 1, 2)

倘若range()返回的是迭代器,那么上面这个看起来在正常不过的代码就有麻烦了:

1

2

3

4

5

>>> numbers = iter(range(3))

>>> tuple(numbers)

(0, 1, 2)

>>> tuple(numbers)

()

总结

Iterator是有状态的,只能遍历一次,是“消费型”的,不可以“二次消费”。Iterable是没有状态的(这里不太严谨,这句话暂且不提是Iterator的Iterable),每一次对Iterable调用iter()都会得到一个新的迭代器。

以上就是python3中的range返回的是迭代器吗?的详细内容,更多文章请关注木庄网络博客!!

相关阅读 >>

Python中x[::]什么意思

都是第一次玩deepfakes

Python怎么读help文件

Python可用于什么领域?

Python以什么划分语句块

Python 读取指定文件夹下的所有图像方法

Python未来发展怎么样

Python中map()函数的方法示例

Python入口函数是什么

Python的爬虫是什么意思

更多相关阅读请进入《Python》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...