如何在Python中反转列表?

时间:2010-10-15 06:59:39

标签: python list

如何在Python中执行以下操作?

array = [0, 10, 20, 40]
for (i = array.length() - 1; i >= 0; i--)

我需要拥有数组的元素,但从结尾到开头。

43 个答案:

答案 0 :(得分:1149)

>>> L = [0,10,20,40]
>>> L[::-1]
[40, 20, 10, 0]

扩展切片语法在Python What's new Entry for release 2.3.5

中得到了很好的解释

在评论this is the most current slice documentation中提出特殊要求。

答案 1 :(得分:1135)

您可以将reversed功能用作:

>>> array=[0,10,20,40]
>>> for i in reversed(array):
...     print(i)

请注意reversed(...)不会返回列表。您可以使用list(reversed(array))获得反向列表。

答案 2 :(得分:334)

>>> L = [0,10,20,40]
>>> L.reverse()
>>> L
[40, 20, 10, 0]

>>> L[::-1]
[40, 20, 10, 0]

答案 3 :(得分:48)

这是为了复制列表:

L = [0,10,20,40]
p = L[::-1]  #  Here p will be having reversed list

这是为了反转列表:

L.reverse() # Here L will be reversed in-place (no new list made)

答案 4 :(得分:42)

我认为在Python中反转列表的最佳方法是:

a = [1,2,3,4]
a = a[::-1]
print(a)
>>> [4,3,2,1]

工作已经完成,现在你有一个反向清单。

答案 5 :(得分:26)

要反转相同的列表,请使用:

array.reverse()

要将反向列表分配到其他列表中,请使用:

newArray = array[::-1] 

答案 6 :(得分:22)

使用切片,例如array = array [:: - 1],是一个巧妙的技巧,非常Pythonic,但对于新手来说可能有点模糊。使用reverse()方法是日常编码的好方法,因为它易于阅读。

但是,如果您需要像面试问题那样撤销列表,您可能无法使用这些内置方法。面试官将研究如何处理问题而不是Python知识的深度,需要一种算法方法。以下示例使用经典交换,可能是一种方法: -

def reverse_in_place(lst):      # Declare a function
    size = len(lst)             # Get the length of the sequence
    hiindex = size - 1
    its = size/2                # Number of iterations required
    for i in xrange(0, its):    # i is the low index pointer
        temp = lst[hiindex]     # Perform a classic swap
        lst[hiindex] = lst[i]
        lst[i] = temp
        hiindex -= 1            # Decrement the high index pointer
    print "Done!"

# Now test it!!
array = [2, 5, 8, 9, 12, 19, 25, 27, 32, 60, 65, 1, 7, 24, 124, 654]

print array                    # Print the original sequence
reverse_in_place(array)        # Call the function passing the list
print array                    # Print reversed list


**The result:**
[2, 5, 8, 9, 12, 19, 25, 27, 32, 60, 65, 1, 7, 24, 124, 654]
Done!
[654, 124, 24, 7, 1, 65, 60, 32, 27, 25, 19, 12, 9, 8, 5, 2]

请注意,这不适用于元组或字符串序列,因为字符串和元组是不可变的,即您无法写入它们来更改元素。

答案 7 :(得分:17)

for x in array[::-1]:
    do stuff

答案 8 :(得分:17)

我发现(与其他一些建议相反)l.reverse()是迄今为止在Python 3和2中反转长列表的最快方法。我有兴趣知道其他人是否可以复制这些时间

l[::-1]可能更慢,因为它会在反转之前复制列表。在list()所做的迭代器周围添加reversed(l)调用必然会增加一些开销。当然,如果你想要一个列表或迭代器的副本,那么使用那些相应的方法,但如果你只想反转列表,那么l.reverse()似乎是最快的方法。

功能

def rev_list1(l):
    return l[::-1]

def rev_list2(l):
    return list(reversed(l))

def rev_list3(l):
    l.reverse()
    return l

列表

l = list(range(1000000))

Python 3.5时间

timeit(lambda: rev_list1(l), number=1000)
# 6.48
timeit(lambda: rev_list2(l), number=1000)
# 7.13
timeit(lambda: rev_list3(l), number=1000)
# 0.44

Python 2.7时间

timeit(lambda: rev_list1(l), number=1000)
# 6.76
timeit(lambda: rev_list2(l), number=1000)
# 9.18
timeit(lambda: rev_list3(l), number=1000)
# 0.46

答案 9 :(得分:16)

具有解释和计时结果的方法概述

有三种不同的内置方法可以反转列表。哪种方法最好取决于您是否需要:

  1. 就地反转现有列表(更改原始列表变量)
    • 最佳解决方案是object.reverse()方法
  2. 创建一个反向列表的迭代器(因为您要将其馈送到for循环,生成器等)
    • 最佳解决方案是创建迭代器的reversed(object)
  3. 以相反的顺序创建列表的副本(以保留原始列表)
    • 最佳解决方案是使用步长为-1的切片:object[::-1]

从速度角度来看,最好使用内置函数来反转列表。在这种情况下,与手动创建的循环或生成器相比,它们在短列表(10个项目)上的速度快2到8倍,而在长列表上的速度快约300倍以上。这是有道理的,因为它们是用本国语言(即C)编写的,并有专家来创建,检查和优化。它们也不太容易出现缺陷,并且更有可能处理边缘和角落情况。

测试脚本

将这个答案中的所有代码段放在一起,以创建一个脚本,该脚本将运行以下所述的不同方式来反转列表。它将在运行100,000次时为每种方法计时。结果显示在最后一节中,列出了长度为2、10和1000的项目。

from timeit import timeit
from copy import copy

def time_str_ms(t):
    return '{0:8.2f} ms'.format(t * 1000)

方法1:使用obj.reverse()进行适当的位置反转

如果目标只是颠倒现有列表中项目的顺序,而不要遍历它们或使副本可用,请使用<list>.reverse()函数。直接在列表对象上运行此命令,所有项目的顺序将颠倒:

请注意,以下内容将反转给定的原始变量,即使它也返回已反转的列表。也就是说,您可以使用此函数输出创建副本。通常,您不会为此创建函数,但是计时脚本需要它。

我们测试了这两种方法的性能-首先只是就地反转列表(更改原始列表),然后复制列表并随后对其进行反转,以查看这是创建反向副本的最快方法。其他方法。

def rev_in_place(mylist):
    mylist.reverse()
    return mylist

def rev_copy_reverse(mylist):
    a = copy(mylist)
    a.reverse()
    return a

方法2:使用切片obj[::-1]颠倒列表

内置的索引切片方法使您可以复制任何索引对象的一部分。

  • 它不会影响原始对象
  • 它将构建完整列表,而不是迭代器

通用语法为:<object>[first_index:last_index:step]。要利用切片来创建简单的反向列表,请使用:<list>[::-1]。将选项保留为空时,它将其设置为对象的第一个和最后一个元素的默认值(如果步长为负,则相反)。

索引允许使用负数,该负数从对象索引的末尾开始向后计数(即-2是倒数第二个)。当步长为负数时,它将从最后一项开始,并以该数量向后索引。

def rev_slice(mylist):
    a = mylist[::-1]
    return a

方法3:使用reversed(obj)迭代器函数反转列表

有一个reversed(indexed_object)函数:

  • 这将创建反向索引迭代器,而不是列表。如果您将其馈入循环以在大型列表上获得更好的性能,那就太好了
  • 这将创建一个副本,并且不会影响原始对象

同时测试原始迭代器和从迭代器创建列表。

def reversed_iterator(mylist):
    a = reversed(mylist)
    return a

def reversed_with_list(mylist):
    a = list(reversed(mylist))
    return a

方法4:使用自定义/手动索引的反向列表

如时间所示,创建自己的索引编制方法不是一个好主意。除非确实需要自定义,否则请使用内置方法。这只是意味着学习内置方法。

也就是说,列表大小较小不会带来巨大的损失,但是当您扩大规模时,损失将变得巨大。我敢肯定,下面的代码可以优化,但是它永远无法与内置方法匹配,因为它们是直接用本机语言实现的。

def rev_manual_pos_gen(mylist):
    max_index = len(mylist) - 1
    return [ mylist[max_index - index] for index in range(len(mylist)) ]

def rev_manual_neg_gen(mylist):
    ## index is 0 to 9, but we need -1 to -10
    return [ mylist[-index-1] for index in range(len(mylist)) ]

def rev_manual_index_loop(mylist):
    a = []
    reverse_index = len(mylist) - 1
    for index in range(len(mylist)):
        a.append(mylist[reverse_index - index])
    return a
    
def rev_manual_loop(mylist):
    a = []
    reverse_index = len(mylist)
    for index, _ in enumerate(mylist):
        reverse_index -= 1
        a.append(mylist[reverse_index])
    return a

对每种方法进行计时

以下是该脚本的其余部分,为每种反向方法计时。它显示了使用obj.reverse()进行原位反转和创建reversed(obj)迭代器总是最快的,而使用切片是创建副本的最快方法。

事实证明,除非必须这样做,否则不要尝试自己创建一种方式!

loops_to_test = 100000
number_of_items = 10
list_to_reverse = list(range(number_of_items))
if number_of_items < 15:
    print("a: {}".format(list_to_reverse))
print('Loops: {:,}'.format(loops_to_test))
# List of the functions we want to test with the timer, in print order
fcns = [rev_in_place, reversed_iterator, rev_slice, rev_copy_reverse,
        reversed_with_list, rev_manual_pos_gen, rev_manual_neg_gen,
        rev_manual_index_loop, rev_manual_loop]
max_name_string = max([ len(fcn.__name__) for fcn in fcns ])
for fcn in fcns:
    a = copy(list_to_reverse) # copy to start fresh each loop
    out_str = ' | out = {}'.format(fcn(a)) if number_of_items < 15 else ''
    # Time in ms for the given # of loops on this fcn
    time_str = time_str_ms(timeit(lambda: fcn(a), number=loops_to_test))
    # Get the output string for this function
    fcn_str = '{}(a):'.format(fcn.__name__)
    # Add the correct string length to accommodate the maximum fcn name
    format_str = '{{fx:{}s}} {{time}}{{rev}}'.format(max_name_string + 4)
    print(format_str.format(fx=fcn_str, time=time_str, rev=out_str))

计时结果

结果表明,使用最适合给定任务的内置方法,缩放效果最佳。换句话说,随着对象元素数量的增加,内置方法开始具有优越的性能结果。

与直接将东西串在一起相比,使用最好的内置方法直接实现所需的效果更好。也就是说,切片是最好的,如果您需要反向列表的副本-它比通过reversed()函数创建列表要快,并且比复制列表然后进行就地obj.reverse()时要快。但是,如果您真正需要这些方法中的任何一种,它们都将更快,但速度永远不会超过两倍。同时-自定义手动方法可能要花几个数量级,特别是列表很大时。

要进行缩放,有1000个项目列表,reversed(<list>)函数调用需要大约30毫秒来设置迭代器,就地反转仅需要大约55毫秒,使用slice方法需要大约210毫秒来创建一个迭代器。完整的反向列表的副本,但是我做的最快的手动方法花费了大约8400毫秒!

列表中有2个项目:

a: [0, 1]
Loops: 100,000
rev_in_place(a):             24.70 ms | out = [1, 0]
reversed_iterator(a):        30.48 ms | out = <list_reverseiterator object at 0x0000020242580408>
rev_slice(a):                31.65 ms | out = [1, 0]
rev_copy_reverse(a):         63.42 ms | out = [1, 0]
reversed_with_list(a):       48.65 ms | out = [1, 0]
rev_manual_pos_gen(a):       98.94 ms | out = [1, 0]
rev_manual_neg_gen(a):       88.11 ms | out = [1, 0]
rev_manual_index_loop(a):    87.23 ms | out = [1, 0]
rev_manual_loop(a):          79.24 ms | out = [1, 0]

列表中有10个项目:

rev_in_place(a):             23.39 ms | out = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
reversed_iterator(a):        30.23 ms | out = <list_reverseiterator object at 0x00000290A3CB0388>
rev_slice(a):                36.01 ms | out = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
rev_copy_reverse(a):         64.67 ms | out = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
reversed_with_list(a):       50.77 ms | out = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
rev_manual_pos_gen(a):      162.83 ms | out = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
rev_manual_neg_gen(a):      167.43 ms | out = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
rev_manual_index_loop(a):   152.04 ms | out = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
rev_manual_loop(a):         183.01 ms | out = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

列表中有1000个项目:

rev_in_place(a):             56.37 ms
reversed_iterator(a):        30.47 ms
rev_slice(a):               211.42 ms
rev_copy_reverse(a):        295.74 ms
reversed_with_list(a):      418.45 ms
rev_manual_pos_gen(a):     8410.01 ms
rev_manual_neg_gen(a):    11054.84 ms
rev_manual_index_loop(a): 10543.11 ms
rev_manual_loop(a):       15472.66 ms

答案 10 :(得分:14)

reversedlist

leaked

答案 11 :(得分:11)

可能的方式,

list1 = [3,4,3,545,6,4,34,243]

list1.reverse()

list1[::-1]

答案 12 :(得分:10)

array=[0,10,20,40]
for e in reversed(array):
  print e

答案 13 :(得分:7)

使用反向(数组)可能是最佳路线。

>>> array = [1,2,3,4]
>>> for item in reversed(array):
>>>     print item

您是否需要了解如何在不使用内置reversed的情况下实现此目的。

def reverse(a):
    midpoint = len(a)/2
    for item in a[:midpoint]:
        otherside = (len(a) - a.index(item)) - 1
        temp = a[otherside]
        a[otherside] = a[a.index(item)]
        a[a.index(item)] = temp
    return a

这应该花费O(N)时间。

答案 14 :(得分:5)

如果您想将反向列表的元素存储在其他变量中,则可以使用revArray = array[::-1]revArray = list(reversed(array))

但第一个变种稍微快一些:

z = range(1000000)
startTimeTic = time.time()
y = z[::-1]
print("Time: %s s" % (time.time() - startTimeTic))

f = range(1000000)
startTimeTic = time.time()
g = list(reversed(f))
print("Time: %s s" % (time.time() - startTimeTic))

输出:

Time: 0.00489711761475 s
Time: 0.00609302520752 s

答案 15 :(得分:5)

组织价值观:

在Python中,列表的顺序也可以用排序进行操作,按数字/字母顺序组织变量:

暂时:

print(sorted(my_list))

常驻:

my_list.sort(), print(my_list)

您可以使用标记“reverse = True”

进行排序
  

print(sorted(my_list, reverse=True))

     

     

my_list.sort(reverse=True), print(my_list)

没有组织

也许您不想对值进行排序,而只是反转值。然后我们可以这样做:

  

print(list(reversed(my_list)))

** 数字优先于列表顺序中的字母。 Python值的组织非常棒。

答案 16 :(得分:4)

使用列表理解:

[array[n] for n in range(len(array)-1, -1, -1)]

答案 17 :(得分:3)

您可以使用reversed()

array=[0,10,20,40]

for e in reversed(array):
  print e

答案 18 :(得分:3)

def reverse(text):
    output = []
    for i in range(len(text)-1, -1, -1):
        output.append(text[i])
    return output

答案 19 :(得分:3)

严格来说,问题不在于如何反向返回列表,而是如何使用示例列表名称array来反转列表。

要撤消名为"array"的列表,请使用array.reverse()

通过使用array = array[::-1]将列表定义为自身的切片修改,所描述的非常有用的切片方法也可用于反转列表。

答案 20 :(得分:3)

您还可以使用数组索引的bitwise complement反向遍历数组:

>>> array = [0, 10, 20, 40]
>>> [array[~i] for i, _ in enumerate(array)]
[40, 20, 10, 0]

无论你做什么,都不要这样做。

答案 21 :(得分:2)

有3种方法可以获取反向列表:

  1. 切片方法1:reversed_array = array[-1::-1]

  2. 切片方法2: reversed_array2 = array[::-1]

  3. 使用内置函数:reversed_array = array.reverse()

第三个函数实际上将列表对象反转到位。这意味着不保留原始数据的副本。如果您不想维护旧版本,这是一个好方法。但是,如果您确实想要原始版本和反向版本,这似乎不是解决方案。

答案 22 :(得分:2)

组织价值观:

在 Python 中,列表的顺序也可以通过 sort 进行操作,按数字/字母顺序组织变量: 暂时:

打印(排序(my_list))

永久:

my_list.sort(), 打印(my_list)

您可以使用标志“reverse=True”进行排序:

print(sorted(my_list, reverse=True))

or

my_list.sort(reverse=True), print(my_list)

没有组织

也许您不想对值进行排序,而只想反转值。然后我们可以这样做:

print(list(reversed(my_list)))

**在列表顺序中数字优先于字母。 Python 价值观的组织很棒。

编辑 1:一个错误的版主声称我的回答是副本并删除了我的旧帖子。

答案 23 :(得分:2)

list_data = [1,2,3,4,5]
l = len(list_data)
i=l+1
rev_data = []
while l>0:
  j=i-l
  l-=1
  rev_data.append(list_data[-j])
print "After Rev:- %s" %rev_data 

答案 24 :(得分:2)

def reverse(text):
    lst=[]
    for i in range(0,len(text)):
        lst.append(text[(len(text)-1)-i])
    return ''.join(lst)

print reverse('reversed')

答案 25 :(得分:2)

您可以始终将列表视为堆栈,只是从列表的后端弹出堆栈顶部的元素。这样你就可以利用堆栈中的第一个特征。当然你正在使用第一个阵列。我喜欢这种方法,因为它非常直观,因为你看到一个列表从后端消耗而另一个列表是从前端构建的。

>>> l = [1,2,3,4,5,6]; nl=[]
>>> while l:
        nl.append(l.pop())  
>>> print nl
[6, 5, 4, 3, 2, 1]

答案 26 :(得分:2)

您的需求最直接的转换为Python for声明:

for i in xrange(len(array) - 1, -1, -1):
   print i, array[i]

这是相当神秘但可能有用。

答案 27 :(得分:2)

使用反向功能,如下所示并打印

>>> for element in reversed(your_array):
...     print element

答案 28 :(得分:2)

def reverse(my_list):
  L = len(my_list)
  for i in range(L/2):
    my_list[i], my_list[L-i - 1] = my_list[L-i-1], my_list[i]
  return my_list

答案 29 :(得分:1)

>>> l = [1, 2, 3, 4, 5]
>>> print(reduce(lambda acc, x: [x] + acc, l, []))
[5, 4, 3, 2, 1]

答案 30 :(得分:1)

通过切换相反指数的参考来反转原位:

>>> l = [1,2,3,4,5,6,7]    
>>> for i in range(len(l)//2):
...     l[i], l[-1-i] = l[-1-i], l[i]
...
>>> l
[7, 6, 5, 4, 3, 2, 1]

答案 31 :(得分:1)

使用一些逻辑

使用一些古老的逻辑来进行面试。

  

从前到后交换数字。使用两个指针index[0] and index[last]

def reverse(array):
    n = array
    first = 0
    last = len(array) - 1
    while first < last:
      holder = n[first]
      n[first] = n[last]
      n[last] = holder
      first += 1
      last -= 1
    return n

input -> [-1 ,1, 2, 3, 4, 5, 6]
output -> [6, 1, 2, 3, 4, 5, -1]

答案 32 :(得分:1)

使用

print(reversed(list_name))

答案 33 :(得分:0)

使用列表推导和 abs 的替代方法

port

答案 34 :(得分:0)

一个干净简单的类对象来解决您的问题。

class lister():
    def reverse(self):
        return  [self[len(self)-e]for e,x in enumerate(self,start=1)]
print(lister.reverse([0, 10, 20, 40]))

答案 35 :(得分:0)

我在面试的 Python 代码测试中遇到了这个问题。 下面是我的回答。 注意它适用于任何长度的任何值

def get_reverse(list_check, count_num):
    final_list =[]
    for index in range(list_length):
        value = list_check[count_num]
        final_list.append(value)
        count_num = count_num -1

    return final_list

new_list = ['A', 'GOAT', 'C', 'D', 'Mac']

list_length = len(new_list)
x = list_length -1

print(get_reverse(new_list, x))

答案 36 :(得分:0)

另一种解决方案是为此使用numpy.flip

import numpy as np
array = [0, 10, 20, 40]
list(np.flip(array))
[40, 20, 10, 0]

答案 37 :(得分:0)

这是一种使用生成器懒惰地评估反向的方法:

def reverse(seq):
    for x in range(len(seq), -1, -1): #Iterate through a sequence starting from -1 and increasing by -1.
        yield seq[x] #Yield a value to the generator

现在像这样迭代:

for x in reverse([1, 2, 3]):
    print(x)

如果您需要列表:

l = list(reverse([1, 2, 3]))

答案 38 :(得分:0)

此类使用Python魔术方法和迭代器进行反转,并反转列表:

class Reverse(object):
    """ Builds a reverse method using magic methods """

    def __init__(self, data):
        self.data = data
        self.index = len(data)


    def __iter__(self):
        return self

    def __next__(self):
        if self.index == 0:
            raise StopIteration

        self.index = self.index - 1
        return self.data[self.index]


REV_INSTANCE = Reverse([0, 10, 20, 40])

iter(REV_INSTANCE)

rev_list = []
for i in REV_INSTANCE:
    rev_list.append(i)

print(rev_list)  

输出

[40, 20, 10, 0]

答案 39 :(得分:0)

假设采访设置是最少的内置功能

array = [1, 2, 3, 4, 5, 6,7, 8]
inverse = [] #create container for inverse array
length = len(array)  #to iterate later, returns 8 
counter = length - 1  #because the 8th element is on position 7 (as python starts from 0)

for i in range(length): 
   inverse.append(array[counter])
   counter -= 1
print(inverse)

答案 40 :(得分:0)

>>> L = [1, 2, 3, 4]
>>> L = [L[-i] for i in range(1, len(L) + 1)]
>>> L
[4, 3, 2, 1]

答案 41 :(得分:0)

可以使用返回生成器的__reverse__来完成。

>>> l = [1,2,3,4,5]
>>> for i in l.__reversed__():
...   print i
... 
5
4
3
2
1
>>>

答案 42 :(得分:-1)

在一个行代码中反向输入用户输入的值:

<div>

      <label htmlForm="identifier">identifier</label>
      <input
        id="identifier"
        name="identifier"
        onChange={handleChange}
        value={state.identifier}
      />
      <label htmlForm="password">password</label>
      <input
        id="password"
        name="password"
        onChange={handleChange}
        value={state.password}
      />
    <button onClick={handleSubmit}></button>
  </div>