使用range()以相反的顺序打印列表?


364

如何range()在Python中生成以下列表?

[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

那[* range(9,-1,-1)]呢?超级pythonic!
onofricamila

Answers:


561

使用reversed()功能:

reversed(range(10))

这更有意义。

更新:

如果您希望将其作为列表(如btk所指出):

list(reversed(range(10)))

更新:

如果只想使用range以达到相同的结果,则可以使用其所有参数。range(start, stop, step)

例如,要生成一个list [5,4,3,2,1,0],可以使用以下命令:

range(5, -1, -1)

它可能不那么直观,但是正如评论所提到的那样,这效率更高,并且正确使用范围用于反向列表。


13
虽然“效率”较低。而且您无法在其上执行切片操作。
雅各布·鲍耶

6
这个答案很清楚而且很容易理解,但是必须是range(10),不是range(9)。另外,如果您想要一个完整的列表(用于切片等),则应该这样做list(reversed(range(10)))
约翰Y

5
这将产生一个迭代器,OP要求以列表的形式返回结果。
btk 2014年

6
在Python生成器上使用“反向”(假设我们知道内置的Python 3范围)在概念上是错误的,并且会教给错误的习惯,即在高级语言编程时不考虑内存/处理复杂性的习惯。
thedk 2015年

7
在Python3中,reversed通常不接受生成器,但接受range。为什么reversed(range(10000))需要为整个列表分配内存?range可以返回实现实现__reversed__有效反向迭代的方法的对象?
avmohan '17

312

使用“范围”内置功能。签名是range(start, stop, step)。这样会产生一个序列,该序列产生的数字以开头start,如果stop已经达到,则以结束,不包括stop

>>> range(9,-1,-1)   
    [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
>>> range(-2, 6, 2)
    [-2, 0, 2, 4]

在Python 3中,这会产生一个非列表range对象,该对象的作用类似于只读列表(但使用的内存较少,特别是大范围内存)。


1
您能否也请解释一下,也可以向我推荐任何适用于python的网站/ pdf图书
ramesh.mimit 2011年

8
@ramesh如果您help(range)在python shell中运行,它将告诉您参数。它们是要开始的数字,要结束的数字(不包括)和要执行的步骤,因此它是从9开始并减去1,直到达到-1(这时它停止不返回,这就是为什么)范围在0处结束)
Michael Mrozek 2011年

3
@ ramesh.mimit:只需转到官方Python站点。那里有完整的文档,包括出色的教程。
约翰Y

5
确实,这是正确的答案,但可以更清楚地说明。 range(start, stop, step) -从数字开始,start直到每次都stop移动为止,除非达到了产量结果step
B先生

43

您可以使用与Python range(10)[::-1]相同的东西,range(9, -1, -1)并且可以说更具可读性(如果您熟悉通用的sequence[::-1]Python习惯用法)。


28

对于那些对迄今收集到的选择的“效率”感兴趣的人...

Jaime RGP的回答使我在按照我自己的建议(通过评论)从字面上看Jason的 “具有挑战性”的解决方案计时重新启动计算机。为了使您免于停机的好奇心,我在这里介绍我的结果(最差优先):

杰森Jason)的答案(也许只是列表理解能力的偏移):

$ python -m timeit "[9-i for i in range(10)]"
1000000 loops, best of 3: 1.54 usec per loop

martineau的答案(如果您熟悉扩展切片语法,则可以阅读):

$ python -m timeit "range(10)[::-1]"
1000000 loops, best of 3: 0.743 usec per loop

MichałŠrajer的答案(公认的答案,非常可读):

$ python -m timeit "reversed(range(10))"
1000000 loops, best of 3: 0.538 usec per loop

bene的回答(第一个,但当时很粗略):

$ python -m timeit "range(9,-1,-1)"
1000000 loops, best of 3: 0.401 usec per loop

使用Val Neekmanrange(n-1,-1,-1)记法很容易记住最后一个选项。


3
在阅读此答案之前,我做了自己的计时,并得到了相同的结果。
Todd Owen

13
for i in range(8, 0, -1)

将解决这个问题。它将输出8到1,并且-1表示反向列表


10

没有意义,reverse因为range方法可以返回反向列表。

当您对n个项目进行迭代并且想要替换返回的列表的顺序时,range(start, stop, step)必须使用range的第三个参数来标识step并将其设置为-1,其他参数应相应地进行调整:

  1. 提供一站式参数为-1(这是以前的价值stop - 1stop等于0)。
  2. 作为开始参数使用n-1

因此,等效的range(n)相反:

n = 10
print range(n-1,-1,-1) 
#[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

6
坦率地说,我觉得这不像reversed(range(n))
Nicholas Hamilton

1
@NicholasHamilton同意您的意见,但是该答案背后的想法是使用更少的资源...(而问题在于只使用范围函数:))
Andriy Ivaneyko

好的,不用担心,我想这取决于情况。例如,如果将范围函数用作循环的索引,则其作用有限,但是,如果将其用于外部循环,则成本将增加……
Nicholas Hamilton

8

除了可读性,reversed(range(n))似乎要比快range(n)[::-1]

$ python -m timeit "reversed(range(1000000000))"
1000000 loops, best of 3: 0.598 usec per loop
$ python -m timeit "range(1000000000)[::-1]"
1000000 loops, best of 3: 0.945 usec per loop

就好像有人在想:)


拥有一些数字是一件好事:)-为什么也没有加range(1000000000-1,-1,-1)呢?

...最好不要timeit range(1000000000-1,-1,-1)在命令行上尝试,而要看我的结果 :-)
Wolf

6

此问题中的要求要求list按降序排列大小为10的整数a 。因此,让我们在python中生成一个列表。

# This meets the requirement.
# But it is a bit harder to wrap one's head around this. right?
>>> range(10-1, -1, -1)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

# let's find something that is a bit more self-explanatory. Sounds good?
# ----------------------------------------------------

# This returns a list in ascending order.
# Opposite of what the requirement called for.
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

# This returns an iterator in descending order.
# Doesn't meet the requirement as it is not a list.
>>> reversed(range(10))
<listreverseiterator object at 0x10e14e090>

# This returns a list in descending order and meets the requirement
>>> list(reversed(range(10)))
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

2
我真的很喜欢三元组-1正是这种模式使它易于维护wrap one's head around this-今天,我了解到,如果它确实必须高效,则可以range(n-1, -1, -1)在以相反顺序遍历范围时使用。

5

您可以使用range()BIF Like来打印反向数字,

for number in range ( 10 , 0 , -1 ) :
    print ( number ) 

输出将是[10,9,8,7,6,5,4,3,2,1]

range()-范围(start,end,increment / decrement),其中start是包含在内的,end是互斥的,而增量可以是任何数字,其行为类似于step


5

经常问到的问题是否range(9, -1, -1)reversed(range(10))Python 3 更好?使用迭代器使用其他语言的人会立即想到,reversed()必须缓存所有值,然后以相反的顺序返回。问题是,reversed()如果对象只是一个迭代器,Python的运算符将不起作用。该对象必须具有以下两项之一才能使reversed()起作用:

  1. 支持len()和整数索引通过[]
  2. __reversed__()实施方法。

如果您尝试对以上均不使用的对象使用reversed(),则会得到:

>>> [reversed((x for x in range(10)))]
TypeError: 'generator' object is not reversible

简而言之,Python reversed()仅用于类似对象的数组,因此它应具有与正向迭代相同的性能。

但是呢range()?那不是发电机吗?在Python 3中,它是生成器,但包装在同时实现以上两者的类中。因此,range(100000)它不会占用大量内存,但仍支持高效的索引编制和反转。

因此,总而言之,您可以在reversed(range(10))不影响性能的情况下使用它。


3

我相信这会有所帮助,

range(5)[::-1]

下面是用法:

for i in range(5)[::-1]:
    print i 

3
range(9,-1,-1)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

13
您的答案说明了为什么reversed(range(10))不那么容易出错。没有冒犯华诺士。只是一个诚实的观察。
米哈尔Šrajer

我不知道在显示器上留下错误的答案是否是标准的。我或某人可以更正甚至删除它吗?
sinekonata 2014年

3
@sine,不,只是留下它,想知道它是如何累积3次投票的...我想您可以标记它以引起主持人注意(18个月前重复的答案,但损坏的除外),不确定是否要删除它。
OGHaza 2014年

供将来参考:仅代码不是VLQ也不应该标记错误答案。向下投票并继续前进,但是在这种情况下标记(无论是NAA还是mod标记)都是错误的。- 点评来源
Zoe

2

不带[::-1]或反向使用-

def reverse(text):
    result = []
    for index in range(len(text)-1,-1,-1):
        c = text[index]
        result.append(c)
    return ''.join(result)

print reverse("python!")

6
为什么有人应该写这个而不是"python!"[::-1]
丹尼尔(Daniel)

1
[9-i for i in range(10)]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

1

您不一定需要使用range函数,只需执行list [::-1]即可,它应该以相反的顺序快速返回列表,而无需使用任何添加。


这似乎是先前答案中建议的解决方案。看来您可能正在尝试对以前的其他答案发表评论-您需要获得更多的声誉,然后才能这样做。
Grisha Levit

1

假设您有一个名为a = {1,2,3,4,5}的列表,现在,如果您要反向打印该列表,则只需使用以下代码。

a.reverse
for i in a:
   print(i)

我知道您问使用范围,但它已经回答。


0
range(9,-1,-1)
    [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

是正确的形式。如果您使用

reversed(range(10))

您不会得到0的情况。例如,假设您的10不是一个神奇的数字,而用于查找的变量是从反向开始的。如果您的n大小写为0,则将不会执行reversed(range(0)),如果您偶然在零索引中包含单个对象,那么将是错误的。


0

我认为,许多人(作为我自己)可能对按反向顺序遍历现有列表的常见情况感兴趣,而不是如标题中所述,而不仅仅是为此类遍历生成索引。

即使对于这种情况,所有正确的答案仍然是完全正确的,但我想指出的是,在Wolf的答案中所做的性能比较仅用于生成索引。因此,我为反向遍历现有列表做了类似的基准测试。

TL; DR a[::-1]是最快的。

先决条件:

a = list(range(10))

杰森的答案

%timeit [a[9-i] for i in range(10)]
1.27 µs ± 61.5 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

martineau的答案

%timeit a[::-1]
135 ns ± 4.07 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

MichałŠrajer的答案

%timeit list(reversed(a))
374 ns ± 9.87 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

贝恩的答案

%timeit [a[i] for i in range(9, -1, -1)]
1.09 µs ± 11.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

如您所见,在这种情况下,无需显式生成索引,因此最快的方法是减少额外操作的方法。

注意:我在JupyterLab中进行了测试,它具有方便的“魔术命令” %timeit。它timeit.timeit在引擎盖下使用标准。经过Python 3.7.3测试

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.