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

Posted

技术标签:

【中文标题】使用 range() 以相反的顺序打印列表?【英文标题】:Print a list in reverse order with range()? 【发布时间】:2011-11-09 07:47:49 【问题描述】:

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

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

【问题讨论】:

那么 [*range(9, -1, -1)] 呢?超级蟒蛇! 【参考方案1】:

使用reversed()函数:

reversed(range(10))

这更有意义。

更新:

如果你希望它是一个列表(正如 btk 指出的那样):

list(reversed(range(10)))

更新:

如果你只想使用range 来达到同样的效果,你可以使用它的所有参数。 range(start, stop, step)

例如,要生成列表[5,4,3,2,1,0],您可以使用以下内容:

range(5, -1, -1)

它可能不那么直观,但正如 cmets 所提到的,这更有效,并且可以正确使用反向列表的范围。

【讨论】:

虽然它“效率较低”。而且你不能对它进行切片操作。 这也会产生一个从 8 到 0 的列表,而不是从 9 到 0。 这将导致为整个范围分配内存,这对于大范围或您不需要所有值来说效率低下。 Python 2 中的 range(9, -1, -1)xrange(9, -1, -1) 会给你一个迭代器。 在 python 生成器中使用“reversed”(假设我们在谈论 Python 3 内置范围)在概念上是错误的,并且在使用高级语言进行编程时教导了不考虑内存/处理复杂性的错误习惯。 在 Python3 中,reversed 通常不接受生成器,但它接受 range。为什么reversed(range(10000)) 需要为整个列表分配内存? range 可以返回一个实现__reversed__ 方法的对象,该方法允许有效的反向迭代?【参考方案2】:

使用“范围”内置函数。签名是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 对象,其功能类似于只读列表(但使用的内存要少得多,尤其是对于大范围而言)。

【讨论】:

能否请您解释一下,也请您向我推荐任何有关python的网站/pdf书籍 @ramesh 如果你在 python shell 中运行help(range),它会告诉你参数。它们是开始的数字,结束的数字(不包括)和要采取的步骤,所以它从 9 开始并减去 1 直到它达到 -1(此时它停止而不返回,这就是为什么范围以 0 结束) @ramesh.mimit:去 Python 官方网站就行了。那里有完整的文档,包括一个很棒的教程。 真的,这是正确的答案,但可以更清楚地解释。 range(start, stop, step) -- 从数字start 开始,除非达到stop,否则会产生结果,每次移动step【参考方案3】:

您可以使用range(10)[::-1],它与range(9, -1, -1) 相同,并且可以说更具可读性(如果您熟悉常见的sequence[::-1] Python 习语)。

【讨论】:

【参考方案4】:

对于那些对迄今为止收集的选项的“效率”感兴趣的人......

Jaime RGP's answer 引导我在定时按照我自己的建议(通过评论)Jason 的有点“具有挑战性”的解决方案之后重新启动我的计算机。为了让好奇的你免去停机时间,我在这里展示我的结果(最差优先):

Jason's answer(也许只是对list comprehension的力量的一次探索):

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

martineau's answer(如果您熟悉extended slices syntax,则可以阅读):

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

Michał Šrajer's answer(已接受,可读性很强):

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

bene's answer(第一个但非常粗略的at that time):

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

使用range(n-1,-1,-1) 符号Val Neekman 很容易记住最后一个选项。

【讨论】:

我在阅读这个答案之前做了自己的计时,得到了相同的结果。 这些时间点很有用,但你还没有说出结论:时间差是如此微不足道,你应该使用最易读的那个,而不用担心它。事实上,可读性最强的 (reversed(...)) 和最快/最不可读的 (range(9,-1,-1)) 之间的差异大约是百万分之一秒。您的用户不会注意到 :-) 但会注意到代码可读性较差可能导致的错误。 忘了补充:它们在这种形式下也没什么用,因为当你迭代数百万个元素时,肯定会有更大的不同。 10 个元素太少,没有特别的意义。【参考方案5】:

使用reverse 没有意义,因为range 函数可以返回反向列表。

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

    提供stop参数为-1(之前的值stop - 1stop等于0)。 作为启动参数使用n-1

所以相当于range(n)的倒序是:

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

【讨论】:

坦率地说,我觉得这不如 reversed(range(n)) 直观 @NicholasHamilton 同意你的观点,但是这个答案背后的想法是使用更少的资源......(问题是关于使用范围函数:)) 好的,不用担心,我想这取决于具体情况。例如,如果 range 函数被用作循环的索引,那么它的效果会很有限,但是,如果它在外部循环中使用,那么成本就会增加......【参考方案6】:
for i in range(8, 0, -1)

将解决这个问题。会输出8比1,-1表示倒序列表

【讨论】:

这将给出8, 7, ... 1 而不是8, 7, ... 0。在某种程度上,这是一个很好的答案,因为它显示了 range(..., -1) 技术有多糟糕。【参考方案7】:

抛开可读性不谈,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),而是查看my results :-)【参考方案8】:

经常被问到的问题是range(9, -1, -1) 在 Python 3 中是否比 reversed(range(10)) 更好?在其他语言中使用过迭代器的人会立即倾向于认为 reversed() 必须缓存所有值,然后以相反的顺序返回。问题是如果对象只是一个迭代器,Python 的 reversed() 运算符就不起作用。要使 reversed() 工作,该对象必须具有以下两个之一:

    通过[] 支持len() 和整数索引 或者实现__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)) 而不会影响性能。

【讨论】:

【参考方案9】:

此问题中的要求要求list 大小为 10 的整数以降序排列 命令。那么,让我们在 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]

【讨论】:

我真的很喜欢三元组-1正是这种模式wrap one's head around this很容易保持-- 今天我了解到,如果它真的必须高效,在逆序遍历范围时使用range(n-1, -1, -1)【参考方案10】:

您可以使用 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 可以是任何数字并且表现得像 step

【讨论】:

【参考方案11】:
range(9,-1,-1)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

【讨论】:

您的回答说明了为什么reversed(range(10)) 不易出错。没有冒犯 Asinox。只是一个诚实的观察。 我不知道展示错误答案是否符合标准。我或其他人可以更正甚至删除它吗? @sine,不,只是离开它,想知道它是如何累积 3 个赞成票的...我想您可以将其标记为版主注意(与 18 个月前的 answer 重复,但已损坏),不确定不管他们是否会删除它。 供所有将来参考:code only is not VLQ 和 wrong answers aren't supposed to be flagged either。投反对票并继续前进,但在这种情况下标记是错误的,无论是 NAA 还是 mod 标记。 - From review【参考方案12】:

使用不带 [::-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!")

【讨论】:

为什么要写这个而不是"python!"[::-1]【参考方案13】:

我相信这会有所帮助,

range(5)[::-1]

下面是用法:

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

【讨论】:

【参考方案14】:

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

尽管对于这种情况,所有正确的答案仍然非常好,但我想指出,在 Wolf's answer 中进行的性能比较仅用于生成索引。因此,我为以相反顺序遍历现有列表制定了类似的基准。

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

注意:如果您想更详细地分析不同的反转方案及其性能,请查看this great answer。

先决条件:

a = list(range(10))

Jason's answer:

%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's answer:

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

Michał Šrajer's answer:

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

bene's answer:

%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 测试

【讨论】:

a[:: - 1] 的情况是最快的,因为你只计算了反转时间。如果你写得公平: * Janson 的回答:%timeit [9-i for i in range (10)] * martineau 的回答:%timeit list(range(10)) [:: - 1] * Michał Šrajer 的回答:%timeit list(reversed(range(10))) * bene 的回答:%timeit list(range(9, -1, -1)) 这些解决方案中的每一个都会给你一个列表。正如@Wolf 所示,最快的解决方案是bene's answer => range (9, -1, -1) @Szczerski 现在,让我们假设 a = [3, 4, 100, 1, 20, -10, 0, 9, 5, 4] 在先决条件中。它会破坏您的代码,但不会破坏我的代码。我的答案是针对 arbitrary 列表已经给出的情况 如果您正在寻找“使用范围 () 以相反顺序打印列表?”问题的答案?你想知道哪种方式最快。这个解决方案是 bene 的答案。但是,如果您正在寻找最快的方式来反转您的列表a = [3, 4, 100, 1, 20, -10, 0, 9, 5, 4],那么请使用reverse() 而不是[:: - 1]a.reverse () 的速度是原来的两倍。 我不同意,或者我仍然错过了你的观点。同样,原始问题的答案大多与a = [0..9] 场景有关。对于更一般的情况,流行答案的时间安排可能会产生误导。我需要自己的时间,所以我做了并在这里分享了它们。我不想要就地反转——我只需要一个简单的列表,其中包含一个反向顺序的原始列表副本。当然,这个测试被大大简化了,结果可能/应该会因测试方案的不同而有所不同。【参考方案15】:
[9-i for i in range(10)]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

【讨论】:

【参考方案16】:

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

【讨论】:

这似乎是previous answer 中建议的解决方案。看来您可能正在尝试对以前的不同答案发表评论 - 您需要获得更多声誉才能做到这一点。【参考方案17】:

假设你有一个列表调用它 a=1,2,3,4,5 现在,如果您想反向打印列表,只需使用以下代码。

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

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

【讨论】:

【参考方案18】:

因为range(n) 产生了一个可迭代对象,所以你可以做各种各样的好事情来产生你想要的结果,例如:

range(n)[::-1]

如果循环没问题,我们可以做一个队列:

a = []
for i in range(n):
    a.insert(0,a)
return a

或者可以使用 reverse() 方法:

reverse(range(n))

【讨论】:

reversed(range(n)) 是否必须扩展内存中的整个范围?【参考方案19】:
range(9,-1,-1)
    [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

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

reversed(range(10))

你不会得到一个 0 案例。例如,假设您的 10 不是一个幻数,并且您用于查找的变量是从反向开始的。如果您的 n 案例为 0,则不会执行 reversed(range(0)) 如果您碰巧在零索引中有一个对象,则这是错误的。

【讨论】:

以上是关于使用 range() 以相反的顺序打印列表?的主要内容,如果未能解决你的问题,请参考以下文章

彩色字符串以相反的顺序打印而不是向前

如何以相反的字节顺序打印变量?

以相反的顺序打印数字的数字

React:以相反的顺序呈现列表

为啥合并打印顺序相反

我在运行代码时遇到错误,该代码接受用户的温度并以相反的顺序打印,为啥会这样?