首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为什么Python3中没有xrange函数?

为什么Python3中没有xrange函数?
EN

Stack Overflow用户
提问于 2013-02-22 07:36:54
回答 6查看 382K关注 0票数 298

最近我开始使用Python3,它缺少xrange带来的伤害。

简单的例子:

  1. Python2:

从时间导入时间as t def count():st = t() x for x in xrange(10000000) if x%4 == 0 et = t() print et-st count()

  1. Python3:

from time import time as t def xrange(x):return iter(range(x)) def count():st = t() x for x in xrange(10000000) if x%4 == 0 et = t() print (et-st) count()

结果分别是:

  1. 1.53888392448
  2. 3.215819835662842

为什么会这样呢?我的意思是,为什么xrange被移除了?这是一个很好的学习工具。对于初学者来说,就像我一样,就像我们所有人在某种程度上一样。为什么要删除它?有人能告诉我正确的PEP吗,我找不到了。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2013-02-22 08:03:11

一些性能测量,使用timeit而不是尝试使用time手动执行。

首先,Apple 2.7.2 64位:

In [37]: %timeit collections.deque((x for x in xrange(10000000) if x%4 == 0), maxlen=0)
1 loops, best of 3: 1.05 s per loop

现在,python.org 3.3.0 64位:

In [83]: %timeit collections.deque((x for x in range(10000000) if x%4 == 0), maxlen=0)
1 loops, best of 3: 1.32 s per loop

In [84]: %timeit collections.deque((x for x in xrange(10000000) if x%4 == 0), maxlen=0)
1 loops, best of 3: 1.31 s per loop

In [85]: %timeit collections.deque((x for x in iter(range(10000000)) if x%4 == 0), maxlen=0) 
1 loops, best of 3: 1.33 s per loop

显然,3.x的range确实比2.x的xrange慢一点。OP的xrange函数与此无关。(这并不奇怪,因为对__iter__插槽的一次性调用不太可能在对循环中发生的任何事情的10000000个调用中可见,但有人提出了这种可能性。)

但它只慢了30%。操作怎么会变得慢2倍呢?好吧,如果我用32位的Python重复同样的测试,我得到的结果是1.58比3.12。所以我的猜测是,这是3.x以损害32位的方式针对64位性能进行优化的另一种情况。

但这真的很重要吗?看看这个,再次使用3.3.0 64位:

In [86]: %timeit [x for x in range(10000000) if x%4 == 0]
1 loops, best of 3: 3.65 s per loop

因此,构建list所需的时间是整个迭代的两倍多。

至于“比Python 2.6+消耗更多的资源”,从我的测试来看,3.x的range看起来和2.x的xrange-and的大小完全一样,即使它是10倍的大小,构建不必要的列表仍然是一个比范围迭代可能做的任何事情都多1000000倍的问题。

deque中使用显式的for循环而不是C循环又如何呢

In [87]: def consume(x):
   ....:     for i in x:
   ....:         pass
In [88]: %timeit consume(x for x in range(10000000) if x%4 == 0)
1 loops, best of 3: 1.85 s per loop

因此,在for语句中浪费的时间几乎与在迭代range的实际工作中浪费的时间一样多。

如果您担心优化range对象的迭代,那么您可能找错了地方。

与此同时,你一直在问为什么xrange被删除了,不管人们多少次告诉你同样的事情,但我再重复一次:它没有被删除:它被重命名为range,而2.x的range才是被删除的。

这里有一些证据证明3.3 range对象是2.x xrange对象(而不是2.x range函数)的直接后代:3.3 range2.7 xrange的源。您甚至可以在文件中的任何位置看到change history (链接到替换了字符串"xrange“的最后一个实例的更改)。

那么,为什么它变慢了呢?

首先,他们增加了很多新功能。另一方面,他们在所有地方都做了各种各样的更改(特别是在迭代内部),这些更改都有轻微的副作用。而且已经有很多工作来戏剧性地优化各种重要的情况,即使它有时会使不太重要的情况稍微悲观一些。综上所述,我并不奇怪现在尽可能快地迭代range的速度变慢了一点。这是那些不太重要的案例之一,没有人会足够在意来关注它。在现实生活中,这种性能差异是代码中的热点,没有人可能会有这样的用例。

票数 188
EN

Stack Overflow用户

发布于 2013-02-22 09:09:29

Python3的范围是Python2的xrange。没有必要用iter把它包裹起来。要获得Python3中的实际列表,需要使用list(range(...))

如果你想要与Python2和Python3一起工作的东西,试试这个

try:
    xrange
except NameError:
    xrange = range
票数 149
EN

Stack Overflow用户

发布于 2013-02-22 07:42:08

Python3的range类型的工作方式与Python2的xrange类似。我不知道为什么您会看到速度变慢,因为如果您直接在range上迭代,xrange函数返回的迭代器就是您所得到的。

我不能在我的系统上重现减速。下面是我测试的方法:

Python 2,带xrange

Python 2.7.3 (default, Apr 10 2012, 23:24:47) [MSC v.1500 64 bit (AMD64)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> import timeit
>>> timeit.timeit("[x for x in xrange(1000000) if x%4]",number=100)
18.631936646865853

使用range的Python3要快一点:

Python 3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012, 10:57:17) [MSC v.1600 64 bit (AMD64)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> import timeit
>>> timeit.timeit("[x for x in range(1000000) if x%4]",number=100)
17.31399508687869

我最近了解到Python3的range类型还有其他一些巧妙的特性,比如对切片的支持:range(10,100,2)[5:25:5] is range(20, 60, 10)

票数 21
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15014310

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档