如何在Python中反向循环?

292

我说的是要像这样做:

for(i=n; i>=1; --i) {
   //do something with i
}

我可以想到在Python中一些方法(如创建一个列表range(1,n+1)并将其反转,使用while--i,...),但我想知道是否有更加优雅的方法。有吗?

编辑: 有人建议我使用xrange()而不是range(),因为range返回列表而xrange返回迭代器。但在Python 3中(我恰好使用的版本),range()返回迭代器而xrange不存在。


3
有些晚了,但我没有看到最简单的解决方案,所以在这里分享一下..........................................................for i in range(n)[::-1] 这将按相反的顺序给出 i。祝好! - Parthik B.
@ParthikB,最后的反转不会创建额外的空间吗?看起来你正在创建一个新的反转数组 - 我可能错了? - BigDreamz
5个回答

447

range()xrange()接受第三个参数来指定步长,这样你就可以这样做:

range(10, 0, -1)

这会给出什么结果

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

但对于迭代,你应该真正使用xrange。所以:

xrange(10, 0, -1)

针对Python 3用户的注意事项:在Python 3中没有单独的rangexrange函数,只有range函数,其遵循Python 2的xrange设计。


9
由于此问题涉及迭代,请使用xrange而不是range(对于小范围没有太大影响,但对于大范围开始产生影响)。 - mzz
15
@mzz -- 仅适用于 Python 2.x - Katriel
4
我使用了 range,只是因为提问者也这样做了。xrangerange 仅在处理 非常 大的范围时才有所区别,例如数百兆字节。此外,在 Python 3.x 中,这种区别已经不存在了。 - Chinmay Kanchi
19
我认为你应该使用range(10, -1, -1)而不是range(10, 0, -1)。因为range(10, 0, -1)会在索引0处停止,结果索引0的值将不会被打印出来。 - Hatim
8
实际上,你应该使用range(n-1, -1, -1),这将提供从零到n-1的值。这个答案和一些评论都存在一的偏移问题。 - Chris Flesher
显示剩余8条评论

254
for x in reversed(whatever):
    do_something()

这适用于基本上所有具有定义顺序的东西,包括 xrange 对象和列表。


18
不,它返回一个迭代器。 - habnabit
1
是的。抱歉。它返回obj.__reversed__方法的结果。因此,默认情况下,生成器对象没有像许多其他可迭代对象一样的属性。即使是reversed(reversed([1,2,3])),也会引发TypeError异常。因此,在许多情况下,您必须在将某些可迭代对象发送到reversed之前创建一个列表,例如reversed([expr(i)for i in iterable if cond(i)])- 如果没有括号,它就会失败。 - Odomontois
5
我认为这应该成为被接受的答案。 - Jamie Nicholl-Shelley
1
这个应该被接受的原因是reversed(range(3))会产生2, 1, 0,正好是range(3)的反转,而你否则需要做类似于range(3-1, 0-1, -1)才能得到相同的结果。它也比range(3)[::-1]更易读。 - Dennis Williamson
这是最佳答案,正如其他评论所述,例如尝试:for i, val in enumerate(reversed(range(6))): print(i, val) - NeilG
这难道不需要在迭代开始时将整个范围分配到内存中吗? - undefined

22
所有这三种解决方案如果输入是字符串,则会得出相同的结果:

1.

def reverse(text):
    result = ""
    for i in range(len(text),0,-1):
        result += text[i-1]
    return (result)

2.

text[::-1]

3.

"".join(reversed(text))

根据不同的情况,哪种方法是推荐的呢? - Ridhwaan Shakeel
#1建议在最新的Python版本上是否仍然有效?我尝试了一下,但出现了“列表索引超出范围”的错误。 - Gel

12
def reverse(text):
    reversed = ''
    for i in range(len(text)-1, -1, -1):
        reversed += text[i]
    return reversed

print("reverse({}): {}".format("abcd", reverse("abcd")))

这是最好的答案。像使用for循环一样迭代值并不是每个人都想要的。通过索引进行迭代更加灵活。 - Urthor
这绝不是最好的答案。如果你想要使用索引进行反向迭代(如果这是你想要的,并且是你用来说这是更好的标准),那么请使用rangereversed,如此答案所述; 这更简单。 - NeilG

2

如果不使用reversed[::-1]来反转字符串,可以尝试以下方法:

def reverse(text):
    # Container for reversed string
    txet=""

    # store the length of the string to be reversed
    # account for indexes starting at 0
    length = len(text)-1

    # loop through the string in reverse and append each character
    # deprecate the length index
    while length>=0:
        txet += "%s"%text[length]
        length-=1
    return txet

2
你为什么想要这样做呢?这相当简单: def reverse(text): new_text = "" for char in text: new_text = char + new_text return new_text - aks

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接