【问题标题】:How to reverse a list?如何反转列表?
【发布时间】:2011-04-25 19:17:41
【问题描述】:

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

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

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

【问题讨论】:

  • 或者更确切地说“我如何反转预先排序的列表?” (鉴于这个使大多数答案脱轨的特殊测试用例,这是一个正确的问题:)

标签: python list


【解决方案1】:
>>> 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

【讨论】:

  • 它适用于任何可交互的,而不仅仅是列表。缺点是没到位。
  • @Tim 它返回一个切片,所以不会改变实际的列表内容
  • @lunixbochs reversed 返回迭代器,而不是 Python 3 中的列表。
  • 除非自然地正确封装在数组中
  • 我同意@Swiss。 +1,因为问题是我需要数组的元素,但从头到尾。 - reversed 返回一个 listreverseiterator 对象(Python 2.7.x),然后必须被迭代 - 反向切片返回一个反向列表/元组/str(取决于你切片的内容)。 @Einar Petersen 正在反转字符串,因此输出是正确的。试试:co2=['ae','ad','ac','ab','aa','z','y','x','w','v','u','t','s','r','q','p','o','n','m','l','k','j','i','h','g','f','e','d','c','b','a'] >>> co2[::-1]
【解决方案2】:
for x in array[::-1]:
    do stuff

【讨论】:

  • 这种切片方式可读性不是很强。 Pythonic 方法是使用 reverse() 方法。 ;-)
  • @SimonM reverse() 绝对是一目了然的好理解。
【解决方案3】:

您可以为此使用reversed 函数:

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

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

【讨论】:

  • 你不能只使用:array[::-1] 吗?
  • @kdlannoy 根据答案中链接的页面,“与扩展切片相比,例如 range(1,4)[::-1],reversed() 更易于阅读,运行速度更快,并且使用的内存大大减少。"
  • 当我测试这个切片时,它的速度大约是原来的两倍(当反转一个 10k 元素列表并从中创建一个列表时)。我没有测试内存消耗。 reverse 可能会更快,如果您之后不需要强制转换到列表。
  • 值得注意的是,这与 reverse([1,2,3]), n.b. 相同。最后的'd' ...这是下面的其他答案之一,它就地执行此操作,而这返回一个迭代器。
  • 为什么使用reversed()而不是切片?阅读 Python 之禅,第 7 条规则:可读性很重要!
【解决方案4】:
>>> L = [0,10,20,40]
>>> L.reverse()
>>> L
[40, 20, 10, 0]

或者

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

【讨论】:

  • [start:stop:step] 所以步长是-1
  • 详情:第一个就地修改列表,第二个只是返回一个新的反向列表,但不修改原始列表。
  • 第二个示例应该是 L=L[::-1] 以实际反转列表,否则您只会反向返回值
  • 假设我有 l= [1,2,3,4,5,6] 并且 n=2 他们的结果必须是 [6,5,1,2,3,4],我们该怎么做呢
  • 你可以这样做:b = l[-n:] b.reverse() l = b + l[:len(l) - n]
【解决方案5】:
array=[0,10,20,40]
for e in reversed(array):
  print e

【讨论】:

    【解决方案6】:

    将您的需求转化为 Python 最直接的方式是这个 for 声明:

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

    这有点神秘,但可能很有用。

    【讨论】:

      【解决方案7】:

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

      array.reverse()
      

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

      newArray = array[::-1] 
      

      【讨论】:

        【解决方案8】:

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

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

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

        【讨论】:

        • 最后一句不正确,这并没有将列表倒置到位;它应该说array[:] = array[::-1]
        【解决方案9】:

        使用列表理解:

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

        【讨论】:

          【解决方案10】:
          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
          

          【讨论】:

          • 最好使用// 楼层除法操作员。
          【解决方案11】:

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

          【讨论】:

          • 下一次,你可能想使用timeit
          【解决方案12】:
          >>> L = [1, 2, 3, 4]
          >>> L = [L[-i] for i in range(1, len(L) + 1)]
          >>> L
          [4, 3, 2, 1]
          

          【讨论】:

            【解决方案13】:
            def reverse(text):
                output = []
                for i in range(len(text)-1, -1, -1):
                    output.append(text[i])
                return output
            

            【讨论】:

              【解决方案14】:

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

              【讨论】:

              • 正在寻找如何在不使用反向功能的情况下做到这一点。谢谢。
              • 或者原地反转使用 list = list.reverse()
              • 列表a是通过值还是通过引用传入的?它是通过尊敬传递的,所以你不需要 return a。您已在 a 的原始内存位置进行了修改
              【解决方案15】:

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

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

              【讨论】:

                【解决方案16】:

                使用切片,例如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]
                

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

                【讨论】:

                • 经典交换可以通过lst[hiindex], lst[i] = lst[i], lst[hiindex] 完成,我认为... ;-)
                • @Samoth 语法不是很清楚,行为也不是很明显。不同的步骤更有意义。
                • 为什么人们说像 array[::-1] 这样的东西是 Python 的? python zen 告诉我们,显式优于隐式和可读性。这样的东西根本不明确和可读。
                • @k4ppa: array[::-1] 非常易读且非常明确如果您了解 Python。 “可读”并不意味着“以前从未使用过 Python 切片的人必须能够阅读它”; [::-1] 反转切片在 Python 中是一个非常常见的习语(你会一直在现有代码中遇到它),如果你经常使用 Python,它是完全可读的。当然,first10 = []for i in range(10): first10.append(array[i]) 清晰明确,但这并不比first10 = array[:10] 更好。
                • 为什么迭代次数是size/2?其背后的逻辑是什么?另外,如果它的长度不是偶数怎么办。那么是 ceil(size/2)
                【解决方案17】:
                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 
                

                【讨论】:

                  【解决方案18】:
                  >>> l = [1, 2, 3, 4, 5]
                  >>> print(reduce(lambda acc, x: [x] + acc, l, []))
                  [5, 4, 3, 2, 1]
                  

                  【讨论】:

                  • 这个解决方案比l[::-1] 慢了大约 4.5k 倍,同时更不清晰。遗憾的是,Python 中的函数式编程相当缓慢。
                  【解决方案19】:

                  通过切换相反索引的引用来就地反转:

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

                  【讨论】:

                  • 适用于奇数列表!
                  • 我的解决方案是对的!你知道python是如何实现索引的。从右到左你有 0,1,2... 从左到右你有 -1,-2,-3.. 等等。要反转一个列表,你把它分成两部分,然后将索引相乘右边是左边减一。
                  【解决方案20】:

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

                  l[::-1] 可能更慢,因为它会在反转列表之前复制列表。在reversed(l) 生成的迭代器周围添加list() 调用必须增加一些开销。当然,如果您想要列表的副本或迭代器,请使用相应的方法,但如果您只想反转列表,那么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
                  

                  【讨论】:

                  • list.reverse 是最快的,因为它原地反转
                  • 你是对的 list.reverse() 是最快的,但你在惩罚 reversed(最好在你想要一个新的list 时使用,只是以相反的顺序迭代现有的list而不改变原始的)和切片(这也避免了改变原始的list,并且当输入很小时通常比reversed更快)。是的,如果您不需要副本,那么复制的任何东西都会更昂贵,但很多时候,您不想改变原始值。
                  • 它看起来像reversed still loses to list.reverse() 即便如此,但鉴于它不会改变输入list,在许多情况下它会更好。 reversed 的损失很小(比 list.reverse() 长约 1/6)。
                  【解决方案21】:

                  也可以使用数组索引的bitwise complement逆向遍历数组:

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

                  无论你做什么,不要这样做;)

                  【讨论】:

                    【解决方案22】:

                    可以使用 __reverse__ 来完成,它返回一个生成器。

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

                    【讨论】:

                      【解决方案23】:

                      使用reversedlist

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

                      【讨论】:

                        【解决方案24】:

                        使用一些逻辑

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

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

                        【讨论】:

                        • 如果我们将列表一分为二并将第一个与最后一个索引交换,时间复杂度将比列出的样本更有效。
                        【解决方案25】:

                        使用最少的内置函数,假设是面试设置

                        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)
                        

                        【讨论】:

                          【解决方案26】:

                          使用

                          print(reversed(list_name))
                          

                          【讨论】:

                          • &lt;list_reverseiterator object at 0x0000021C517D3DA0&gt;
                          • 此输出不可读...请改用print(list(reversed(list_name)))
                          【解决方案27】:

                          在一行代码中反转用户输入值:

                          for i in input()[::-1]: print(i,end='')
                          

                          【讨论】:

                            【解决方案28】:

                            该类使用 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]
                            

                            【讨论】:

                              【解决方案29】:

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

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

                              【讨论】:

                                【解决方案30】:

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

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

                                【讨论】:

                                • 很棒,非常难忘。并且与其他解决方案不同(对于这种非通用测试用例的 OP 感到羞耻),它甚至适用于未排序的列表(随机数等)。
                                猜你喜欢
                                • 1970-01-01
                                • 2020-12-02
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                • 2021-10-09
                                • 1970-01-01
                                相关资源
                                最近更新 更多