问题:如何在Python中反转列表?

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

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

我需要一个数组的元素,但是要从头到尾。

How can I do the following in Python?

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

I need to have the elements of an array, but from the end to the beginning.


回答 0

您可以通过以下方式使用该reversed函数:

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

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

You can make use of the reversed function for this as:

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

Note that reversed(...) does not return a list. You can get a reversed list using list(reversed(array)).


回答 1

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

扩展片语法在Python 新增功能条目中得到了很好的解释2.3.5

根据注释中的特殊要求,这是最新的slice文档

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

Extended slice syntax is explained well in the Python What’s new Entry for release 2.3.5

By special request in a comment this is the most current slice documentation.


回答 2

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

要么

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

Or

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

回答 3

这是复制列表:

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)

This is to duplicate the list:

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

This is to reverse the list in-place:

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

回答 4

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

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

该工作已完成,现在您有一个反向列表。

I think that the best way to reverse a list in Python is to do:

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

The job is done, and now you have a reversed list.


回答 5

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

array.reverse()

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

newArray = array[::-1] 

For reversing the same list use:

array.reverse()

To assign reversed list into some other list use:

newArray = array[::-1] 

回答 6

使用切片,例如array = array [::-1]是一个巧妙的技巧,非常具有Python风格,但是对于新手来说可能有些晦涩。使用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]

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

Using slicing, e.g. array = array[::-1], is a neat trick and very Pythonic, but a little obscure for newbies maybe. Using the reverse() method is a good way to go in day to day coding because it is easily readable.

However, if you need to reverse a list in place as in an interview question, you will likely not be able to use built in methods like these. The interviewer will be looking at how you approach the problem rather than the depth of Python knowledge, an algorithmic approach is required. The following example, using a classic swap, might be one way to do it:-

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]

Note that this will not work on Tuples or string sequences, because strings and tuples are immutable, i.e., you cannot write into them to change elements.


回答 7

我发现(与其他建议相反)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

I find (contrary to some other suggestions) that l.reverse() is by far the fastest way to reverse a long list in Python 3 and 2. I’d be interested to know if others can replicate these timings.

l[::-1] is probably slower because it copies the list prior to reversing it. Adding the list() call around the iterator made by reversed(l) must add some overhead. Of course if you want a copy of the list or an iterator then use those respective methods, but if you want to just reverse the list then l.reverse() seems to be the fastest way.

Functions

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

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

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

List

l = list(range(1000000))

Python 3.5 timings

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 timings

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

回答 8

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

回答 9

reversedlist

>>> list1 = [1,2,3]
>>> reversed_list = list(reversed(list1))
>>> reversed_list
>>> [3, 2, 1]

With reversed and list:

>>> list1 = [1,2,3]
>>> reversed_list = list(reversed(list1))
>>> reversed_list
>>> [3, 2, 1]

回答 10

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

回答 11

使用reversed(array)可能是最佳途径。

>>> 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)时间。

Using reversed(array) would be the likely best route.

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

Should you need to understand how could implement this without using the built in 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

This should take O(N) time.


回答 12

如果要将反向列表的元素存储在其他变量中,则可以使用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

If you want to store the elements of reversed list in some other variable, then you can use revArray = array[::-1] or revArray = list(reversed(array)).

But the first variant is slightly faster:

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))

Output:

Time: 0.00489711761475 s
Time: 0.00609302520752 s

回答 13

组织值:

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

暂时:

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价值观的组织很棒。

ORGANIZING VALUES:

In Python, lists’ order too can be manipulated with sort, organizing your variables in numerical/alphabetical order:

Temporarily:

print(sorted(my_list))

Permanent:

my_list.sort(), print(my_list)

You can sort with the flag “reverse=True”:

print(sorted(my_list, reverse=True))

or

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

WITHOUT ORGANIZING

Maybe you do not want to sort values, but only reverse the values. Then we can do it like this:

print(list(reversed(my_list)))

**Numbers have priority over alphabet in listing order. The Python values’ organization is awesome.


回答 14

带有解释和计时结果的方法摘要

有几个很好的答案,但是分布广泛,并且大多数没有指出每种方法的根本区别。

总体而言,最好使用内置函数/方法来进行反转,就像几乎所有函数一样。在这种情况下,与手动创建索引方法相比,它们在短列表(10个项目)上的速度大约快2到8倍,而在长列表上的速度快约300倍以上。这是有道理的,因为他们有专家来创建,检查和优化。它们还不太容易出现缺陷,并且更有可能处理边缘和角落情况。

还考虑是否要:

  1. 反转现有清单
    • 最好的解决方法是“ object.reverse()”方法
  2. 创建一个与列表相反的迭代器(因为您要将其馈送到for循环,生成器等)。
    • 最好的解决方案是’reversed(object)`,它可以创建迭代器
  3. 或创建相反顺序的完整副本
    • 最佳解决方案是使用-1步长的切片: object[::-1]

测试脚本

这是我所测试方法的开始。将这个答案中的所有代码片段放在一起,以创建一个脚本,该脚本将运行所有不同的方式来反转列表和时间(上一节中显示的输出)。

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

Summary of Methods with Explanation and Timing Results

There are several good answers, but spread out and most don’t indicate the fundamental differences of each approach.

Overall, it is better to use built-in functions/methods to reverse, as with just about any function. In this case, they are roughly 2 to 8 times faster on short lists (10 items), and up to ~300+ times faster on long lists compared to manually created a means of indexing. This makes sense as they have experts creating them, scrutiny, and optimization. They are also less prone to defects and more likely to handle edge and corner cases.

Also consider whether you want to:

  1. Reverse an existing list in-place
    • Best solution is `object.reverse()’ method
  2. Create an iterator of the reverse of the list (because you are going to feed it to a for-loop, a generator, etc.)
    • Best solution is ‘reversed(object)` which creates the iterator
  3. or create a complete copy that is in the reverse order
    • Best solution is using slices with a -1 step size: object[::-1]

Test Script

Here is the start of my test script for the methods covered. Put all the code snippets in this answer together to make a script that will run all the different ways of reversing a list and time each one (output shown in the last section).

from timeit import timeit
from copy import copy

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

Method 1: Reverse in place with obj.reverse()

If the goal is just to reverse the order of the items in an existing list, without looping over them or getting a copy to work with, use the <list>.reverse() function. Run this directly on a list object, and the order of all items will be reversed:

Note that the following will reverse the original variable that is given, even though it also returns the reversed list back. i.e. you can create a copy by using this function output. Typically, you wouldn’t make a function for this, but I did so to use the timing code at the end.

We’ll test the performance of this two ways – first just reversing a list in-place (changes the original list), and then copying the list and reversing it afterward.

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

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

Method 2: Reverse a list using slices obj[::-1]

The built-in index slicing method allows you to make a copy of part of any indexed object.

  • It does not affect the original object
  • It builds a full list, not an iterator

The generic syntax is: <object>[first_index:last_index:step]. To exploit slicing to create a simple reversed list, use: <list>[::-1]. When leaving an option empty, it sets them to defaults of the first and last element of the object (reversed if the step size is negative).

Indexing allows one to use negative numbers, which count from the end of the object’s index backwards (i.e. -2 is the second to last item). When the step size is negative, it will start with the last item and index backward by that amount. There is some start-end logic associated with this that has be optimized.

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

Method 3: Reverse a list with the reversed(obj) iterator function

There is a reversed(indexed_object) function:

  • This creates a reverse index iterator, not a list. Great if you are feeding it to a loop for better performance on large lists
  • This creates a copy and does not affect the original object

Test with both a raw iterator, and creating a list from the iterator.

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

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

Method 4: Reverse list with Custom/Manual indexing

As the timing will show, creating your own methods of indexing is a bad idea. Use the built-in methods unless you need to do something really custom.

That said, there is not a huge penalty with smaller list sizes, but when you scale up the penalty becomes tremendous. I’m sure my code below could be optimized, but I’ll stick with the built-in methods.

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

Timing each method

Following is the rest of the script to time each method of reversing. It shows reversing in place with obj.reverse() and creating the reversed(obj) iterator are always the fastest, while using slices is the fastest way to create a copy.

It also proves not to try to create a way of doing it on your own unless you have to!

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))

Timing Results

The results show that scaling works best with the built-in methods best suited for a given task. In other words, as the object element count increases, the built-in methods begin to have far superior performance results.

You are also better off using the best built-in method that directly achieves what you need than to string things together. i.e. slicing is best if you need a copy of the reversed list – it’s faster than creating a list from the reversed() function, and faster than making a copy of the list and then doing an in-place obj.reverse(). But if either of those methods are really all you need, they are faster, but never by more than double the speed. Meanwhile – custom, manual methods can take orders of magnitude longer, especially with very large lists.

For scaling, with a 1000 item list, the reversed(<list>) function call takes ~30 ms to setup the iterator, reversing in-place takes just ~55 ms, using the slice method takes ~210 ms to create a copy of the full reversed list, but the quickest manual method I made took ~8400 ms!!

With 2 items in the list:

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]

With 10 items in the list:

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]

And with 1000 items in the list:

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

回答 15

使用一些逻辑

使用一些古老的逻辑来练习面试。

从前到后交换数字。使用两个指针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]

Using some logic

Using some old school logic to practice for interviews.

Swapping numbers front to back. Using two pointers 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]

回答 16

您还可以使用数组索引的按位补码来反向遍历数组:

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

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

You can also use the bitwise complement of the array index to step through the array in reverse:

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

Whatever you do, don’t do it this way.


回答 17

使用清单理解:

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

Use list comprehension:

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

回答 18

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

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

Another solution would be to use numpy.flip for this

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

回答 19

严格来说,问题不是如何反向返回列表,而是如何反向显示带有示例列表名称的列表array

要反转一个名为"array"use 的列表array.reverse()

通过使用将列表定义为自身的切片修改,还可以使用如上所述非常有用的切片方法将列表反向显示array = array[::-1]

Strictly speaking, the question is not how to return a list in reverse but rather how to reverse a list with an example list name array.

To reverse a list named "array" use array.reverse().

The incredibly useful slice method as described can also be used to reverse a list in place by defining the list as a sliced modification of itself using array = array[::-1].


回答 20

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

回答 21

使用最少的内置功能(假设它是采访设置)

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)

With minimum amount of built-in functions, assuming it’s interview settings

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)

回答 22

您的需求到Python中最直接的翻译是以下for语句:

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

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

The most direct translation of your requirement into Python is this for statement:

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

This is rather cryptic but may be useful.


回答 23

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
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

回答 24

您总是可以像对待堆栈一样对待列表,只是将元素从列表的后端弹出堆栈顶部。这样,您就可以利用堆栈的后进先出特性。当然,您正在使用第一个数组。我确实喜欢这种方法,因为它非常直观,您可以看到一个列表是从后端使用的,而另一个列表是从前端构建的。

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

You could always treat the list like a stack just popping the elements off the top of the stack from the back end of the list. That way you take advantage of first in last out characteristics of a stack. Of course you are consuming the 1st array. I do like this method in that it’s pretty intuitive in that you see one list being consumed from the back end while the other is being built from the front end.

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

回答 25

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 
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 

回答 26

采用

print(reversed(list_name))

use

print(reversed(list_name))

回答 27

这是一种使用生成器懒洋洋地求逆的方法:

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]))

Here’s a way to lazily evaluate the reverse using a generator:

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

Now iterate through like this:

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

If you need a list:

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

回答 28

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

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

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

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

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

There are 3 methods to get the reversed list:

  1. Slicing Method 1: reversed_array = array[-1::-1]

  2. Slicing Method 2: reversed_array2 = array[::-1]

  3. Using the builtin function: reversed_array = array.reverse()

The third function actually reversed the list object in place. That means no copy of pristine data is maintained. This is a good approach if you don’t want to maintain the old version. But doesn’t seem to be a solution if you do want the pristine and reversed version.


回答 29

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

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。