`range(n,-1,-1)`和`reverse(range(0,n + 1))`之间有什么区别吗?

时间:2015-04-12 18:15:23

标签: python python-3.x

他们产生相同的结果。

>>> for i in range(10, -1, -1):
...     print(i)
... 
10
9
8
7
6
5
4
3
2
1
0

与:

对比
>>> for i in reversed(range(0, 10 + 1):
...     print(i)
... 
10
9
8
7
6
5
4
3
2
1
0

据我所知,Python3的range创建了一个生成器而不是将整个范围存储在内存中。我认为reversed同样会产生一个价值观。有没有理由使用其中一个?

4 个答案:

答案 0 :(得分:3)

这是在两个模块上使用timeit的结果

bhargav@bhargav:~$ python -m timeit "for i in range(10, -1, -1):(i)"
1000000 loops, best of 3: 0.466 usec per loop
bhargav@bhargav:~$ python -m timeit "for i in reversed(range(0, 10 + 1)):(i)"
1000000 loops, best of 3: 0.531 usec per loop

如您所见,第二种方式较慢,因为它对函数reversed进行了额外调用。

答案 1 :(得分:3)

Python中的reversed()函数有一个特殊情况,当你传递range()时。 reversed(range(...))range(...)之间唯一真正的区别是,您可以多次迭代range(),但reversed()会返回迭代器,因此只能使用一次。

>>> iter(range(0, 10))
<range_iterator object at 0x7f735f5badb0>
>>> reversed(range(0, 10))
<range_iterator object at 0x7f735f5baf30>

您可以看到,在这两种情况下,迭代器类型都是range_iterator。因此,在这两种情况下,循环本身的性能都是相同的。

由于reversed()的唯一开销是一次额外的函数调用,我总是更喜欢reversed(range(10))而不是range(9, -1, -1)

答案 2 :(得分:2)

reversed使它成为一个迭代器,所以根据你使用它的方式存在差异:

In [1]: r =  reversed(range(0, 10 + 1))

In [2]: next(r)
Out[2]: 10

In [3]: r = range(10, -1, -1)

In [4]: next(r)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-4-0b5056469c9c> in <module>()
----> 1 next(r)

TypeError: 'range' object is not an iterator

答案 3 :(得分:1)

range(-n+1, -1, -1)reversed(range(n))之间唯一真正的区别是range()返回一个范围对象,可以在迭代之前进一步使用/操作。而reversed()返回一个迭代器 - 你只能迭代它。

使用范围对象的示例,使用迭代器无法完成。

rng = range(20, 40, 2)
length = len(rng)
element = rng[0]
index_of_element = rng.index(element)
membership_test = 0 in rng
new_rng_from_slice = rng[2:5]

由于范围对象可以被切片,这也开启了以另一种方式反转它们的可能性:

assert range(n)[::-1] == range(-n+1, -1, -1)

但是,除非需要范围对象的附加功能,否则reversed(range(n))非常受欢迎,因为它更容易理解。