【问题标题】:How to reverse the elements in a sublist?如何反转子列表中的元素?
【发布时间】:2016-10-02 20:06:54
【问题描述】:

我正在尝试创建一个函数来反转列表中元素的顺序,并反转子列表中的元素。例如:

例如,如果 L = [[1, 2], [3, 4], [5, 6, 7]] 则 deep_reverse(L) 将 L 变为 [[7, 6, 5], [4 , 3], [2, 1]]

我想出了如何反转一个列表的顺序,但是我在反转子列表中元素的顺序时遇到了麻烦。这是我目前所拥有的:

def deep_reverse(L)
    """ 
    assumes L is a list of lists whose elements are ints
    Mutates L such that it reverses its elements and also 
    reverses the order of the int elements in every element of L. 
    It does not return anything.
    """
    for i in reversed(L):
          print(i)

在上面的示例中,我的代码只会打印[5,6,7], [3,4], [1,2],这不是我想要完成的。它只是颠倒列表的顺序,而不是列表中的实际元素。

我应该在代码中添加什么以便它也反转子列表中元素的顺序?

[EDIT:我的代码需要改变列表;我不希望它只是打印它,它实际上需要更改列表。]

【问题讨论】:

  • 感谢大家的帮助!我将 Charles 的答案标记为正确,但我也从 geo1230 和 Stefan Pochmann 那里得到了很多有用的反馈

标签: python list python-3.x reverse sublist


【解决方案1】:
[sublist[::-1] for sublist in to_reverse[::-1]]

列表理解在这里有效。 [::-1]reversed基本相同,只是不修改列表。

编辑:

如下所述,reversed 不会修改列表。它返回一个listreverseiterator 对象

更多编辑:

如果您想要任意深度列表的解决方案,请尝试:

def deep_reverse(to_reverse):
    if isinstance(to_reverse, list):
        return list(map(deep_reverse, to_reverse[::-1]))
    else:
        return to_reverse

更多编辑:

在函数中改变列表:

L[:] = new_list 

将就地修改列表。

【讨论】:

  • reversed 也不修改列表。
  • 编辑解决方案也不会修改L,只是返回反转版本。检查 OP 的规范,这不是必需的行为。
  • 要更改列表,请在 map 之前执行 to_reverse.reverse() 并省略 [::-1]
  • @PatrickHaugh 当我这样做时,它给出了一个 TypeError: takes no arguments (1 given) 这是什么问题?
  • 您是否尝试将参数传递给reverse
【解决方案2】:

我正在尝试创建一个函数来反转列表中元素的顺序,并反转子列表中的元素。

那就做这两件事吧:

L.reverse()
for sublist in L:
    sublist.reverse()

完整的演示,因为你似乎对你的函数应该做什么以及如何测试它感到困惑:

>>> def deep_reverse(L):
        """ 
        assumes L is a list of lists whose elements are ints
        Mutates L such that it reverses its elements and also 
        reverses the order of the int elements in every element of L. 
        It does not return anything.
        """
        L.reverse()
        for sublist in L:
            sublist.reverse()

>>> L = [[1, 2], [3, 4], [5, 6, 7]]
>>> deep_reverse(L)
>>> print(L)
[[7, 6, 5], [4, 3], [2, 1]]

【讨论】:

  • 如何让这个返回 L?
  • @EllaP 与return L?
  • 是的,但是在 for 循环内部还是外部?我只是想确定一下。
  • @EllaP 虽然您的函数记录为“它不返回任何内容”。所以你不应该。
  • @EllaP 当然不在。你也可以尝试一下,不是吗?
【解决方案3】:

您也可以使用map() 来实现:

>>> map(lambda x: x[::-1], L[::-1])       # In Python 2.x
[[7, 6, 5], [4, 3], [2, 1]]

>>> list(map(lambda x: x[::-1], L[::-1])) # In Python 3.x
[[7, 6, 5], [4, 3], [2, 1]]

查看Lambda, filter, reduce and map 上的博客,了解lambda 的功能和map() 在Python 中的工作原理。

【讨论】:

    【解决方案4】:

    这应该可以解决问题。

    L = [[1, 2], [3, 4], [5, 6, 7]]
    
    def deep_reverse(L):
        for i in range(len(L)):
            L[i]=L[i][::-1]
        L=L[::-1]
        return L
    

    【讨论】:

    • @EllaP 你所说的“变异”是什么意思?如果您的意思是按照您想要的方式重新排列列表,那么可以。此外,无论子列表的数量或子列表中的元素数量如何,都可以在根本不修改它的情况下使用此代码的编写方式。希望对您有所帮助!
    • 我相信这只是颠倒了子列表中元素的顺序。代码还需要反转列表中的实际子列表。
    • (我删除了之前的评论,因为我意识到它确实像我想要的那样改变了列表。)
    • @EllaP @geo1230 实际上在函数中使用时,上面的代码并没有正确反转全局L。它将反转子列表。但是当您执行L = L[::-1] 时,您只是在本地范围内创建了一个新的L。您需要使用L.reverse() 修改全局L
    • @geo1230 仍然不适用于最新的编辑。您仍然只是在本地范围内使用L=L[::-1] 行创建一个新的L。通过添加 return L 并不能解决此问题。请注意规范:“Mutates L 使得它反转它的元素...... 它不返回任何东西。”同样,您需要使用list.reverse() 来反转@987654331 @到位。
    【解决方案5】:

    这看起来很熟悉:)。我不会给出完整的解决方案,但这里有一些提示:

    如您所知,有两个步骤,将每个子列表反转,然后将外部列表反转(到位,不创建新列表,因此会变异全局L)。

    所以你可以遍历外部列表,并对每个子列表进行变异:

    for i in range(len(L)):
        # if L[i] is a list:
            # reverse with [::-1] and update L[i] to the reversed version
    # reverse the outer list L, list.reverse() will operate in-place on L
    

    现在请记住,如果您像这样遍历列表:

    for item in list:
        item = 'xxx'
    

    你不能用上面的代码改变itemitem 是一个占位符值,因此更改它实际上不会修改列表。

    您需要为 L 中的项目编制索引,而 enumerate 可以帮助您解决此问题,或者您可以使用上述不太受欢迎的 range(len())

    for i, item in enumerate(L):
        # do something with L[i]
        L[i] = 'something'
    

    编辑:由于对此有很多困惑,我将继续发布基于 Stefan Pochmann 非常优雅的答案的工作解决方案:

    def deep_reverse(L):
        L.reverse()
        for sublist in L:
            sublist.reverse()
    

    请注意,没有 return 语句,也没有 print 语句。这将正确地修改L。您不能在函数内部重新分配L,因为这样它只会创建一个新的本地版本的L,并且不会修改全局L。您可以使用list.reverse() 修改L 就地,根据规范进行必要的修改。

    【讨论】:

      【解决方案6】:

      具有功能范式和防御性编程:

      def deep_reverse(L):
          """ assumes L is a list of lists whose elements are ints
          Mutates L such that it reverses its elements and also 
          reverses the order of the int elements in every element of L. 
          It does not return anything.
          """
          # Your code here
          for i in L:
              try:
                  deep_reverse(i)
              except:
                  pass
          L.reverse()
      

      【讨论】:

        【解决方案7】:

        你可以让它递归,所以它适用于任意深度的嵌套。

        类似(未测试):

        def deep_reverse(L)
            """ 
            assumes L is a list of lists whose elements are ints
            Mutates L such that it reverses its elements and also 
            reverses the order of the int elements in every element of L. 
            It does not return anything.
            """
            for i in reversed(L):
                  if len(i) > 1:
                      deep_reverse(i)
                  else:
                      print(i)
        

        【讨论】:

        • len 不是length。此外,len(int) 将引发 TypeError
        • 你可能想要if isinstance(i, list) and len(i) > 1 或类似的东西。
        • 虽然这不会返回任何内容或实际修改L,但我认为它不会起作用。
        • 你的代码打印了一个 typeError: object of type 'int' has no len() 这是为什么?
        • @EllaP 查看我的评论和建议的编辑。如果你不检查i 是否是一个列表,len() 会抛出一个错误。虽然这两种方式都行不通。
        猜你喜欢
        • 2021-05-24
        • 2021-10-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多