社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

Python3的range比Python2的xrange功能更强大

Python程序员 • 6 年前 • 710 次点击  

Python部落(python.freelycode.com)组织翻译,禁止转载,欢迎转发。

如果你在Python2和Python3之间切换使用,你可能会认为Python2中的xrange和Python3中的range功能是一样的。看起来仅仅是把xrange更名为range罢了,是吗?

但是情况并非如此。

与Python3的range相比,Python2的xrange有点受到限制了。本文将探究Python2中的xrange和Python3中的range之间的差异。

写作本文的灵感来自去年在每周Pyhon会谈中对range对象提出的一个问题。

Python2 vs Python3: range

首先需要来说明下range在Python2和Python3中分别是如何工作的。
在Python2中,range函数返回一个整数列表:

xrange类代表的是一个迭代器,对其遍历可获得同样的结果。但是它是惰性的:

Python3中也存在这种惰性。在Python3中,原先的range函数被移除掉了,并将xrange更名为range:

所以,若你想要在Pyhon3中实现类似Python2中的range的功能,就必须将range对象转化为一个列表:

好吧,现在让我们来比较Python2中的xrange类和Python3中的range类。

相似性

在探究xrange和range对象之间的差异之前,让我们先看一看两者之间的相似性。
Python2中的xrange具有描述性字符串表示形式:

Python3中的range对象同样如此:

Python2中的xrange对象是一个迭代器(任何可遍历的事物称为迭代器):

Python3中的range对象也是迭代器:

xrange对象有起点、终点和步长。步长和起点都是可选择的:

range对象也是如此:

两者都有长度,并且都可进行正序或者倒序索引:

Python将range和xranges都视为序列:

xrange和range在基本功能方面存在许多相似性。接下来,让我们谈论两者之间的区别。

双下标方法

第一个不同之处是Python2的xrange和Python3的range的内置文档。
如果使用help函数请求xrange文档,我们将会看到许多双下标方法。在Python中使用双下标方法对对象进行运算符操作(像+或者*),同样也可对不同对象间共享的特征进行操作(像len和str函数)。
以下为Python2中的xrange对象实现的核心双下标方法:

以下为Python3中的range对象实现的核心双下标方法:

注意,range对象要比xrange支持更多的操作运算符。让我们看一下其中的一些。

可比性

Python3中的range支持相等性检查:

python2中的xrange对象看起来也支持相等性检查:

但是,实际上采用的是Python默认的一致性检查:

两个xrange对象将不会被视为相等的,除非它们实际上是同一个对象。

但是,在Python3中对两个range对象进行比较时,实际上是检查每个对象的起点、终点和步长是否相同:

切片

我们已经看到Python2中的xrange和Python3中的range都支持索引:

Python3中的range对象也支持切片:

但是,xrange却不支持切片:

包含性

range和xrange都支持包含性检查:

但是,xrange对此的支持是有迷惑性的。实际上,Python2中的xrange对象没有实现__contains__方法,而此方法是用来实现Python中的in操作符的。
所以,当我们请求一个xrange对象是否包含一个数字时,为了得到结果,Python会对xrange对象进行遍历,直到找到相应的匹配值。

这在我的电脑上的Python 2.7.12 中运行时大约耗时20s:

但是,在Python3中运行时可立刻返回结果:

Python3能够立刻返回range对象的结果,因为结果是基于提供的起点、终点和步长计算而得到的。

起点、终点和步长

在Python3中,range对象有起点、终点和步长:

这些在运用或者扩展range的性能方面是有用的。

例如:我们可能希望对range对象进行取反,得到range对象在数轴相反方向上的镜像。

虽然range对象不支持此功能,但我们可以通过对起点、终点和步长进行取反实现相似的功能,创建一个新的range对象:

虽然,起点、终点和步长可作为Python2中的xrange对象的参数,但是xrange对象并不具备这些属性:

如果你想要得到xrange对象的起点、终点和步长,你需要手动对其进行计算。像这样的代码可能会起作用:

支持大数

这是不实用的最后一点区别。但是,对于range和xrange的一些趣味性使用案例可能是重要的。
Python3中的range对象可接受任何大小的整数:

但是,Python2中的xrange对象受限于接受的整数大小:

我经常会在现场团队教学环节碰到这种区别,因为在授课时,我有时会使用含有大数这样的不实用的例子。


这些重要吗?


很多时候,你在使用Python2中的xrange对象或是Python3中的range对象时,可能只是创建它们并立刻进行遍历:

所以,我前面提到的那些xrange的隐藏功能在大多数时候就显得不那么重要了。
然而,在对一系列连续整数进行诸如切片、快速包含性检查和相等性检查等操作时就显得有用多了。在这些情况下,Python2使用者倾向于使用range函数,返回一个列表。但是在Python3中的range类中,你总会找到你所想要的东西。几乎对于每次要进行的操作,Python3中的range具有速度快,内存节约并且功能强大。
Python3着力确保内置函数节约内存并具有更快的运行速度。许多内置函数(比如:zip,map和filter)现在返回的是迭代器和惰性对象,而不是列表了。

同时,Python3使得一些常见函数,像range等,更富有特性。
相较于Python2,Python3作出了许多较大的改善。但是,也存在升级到Python3时只带来许多微小益处的情况。如果您还没有进行升级,我强烈建议您认真思考下是否有意义将代码升级到Python3版本。


英文原文:http://treyhunner.com/2018/02/python-3-s-range-better-than-python-2-s-xrange/
译者:左风



今天看啥 - 高品质阅读平台
本文地址:http://www.jintiankansha.me/t/r9BImpRt5v
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/7686
 
710 次点击