【问题标题】:Adding new element at the end in each internal list of list in Python在Python中每个内部列表列表的末尾添加新元素
【发布时间】:2018-02-25 05:31:45
【问题描述】:

我有一个如下列表:

[[1,345,0,304],[0,345,678,946,90],[0,23,3,56,3,5,9,0]]

现在我想在每个内部列表的末尾附加一个新数字(相同的数字)。

所以结果应该是这样的:

[[1,345,0,304,90],[0,345,678,946,90,90],[0,23,3,56,3,5,9,0,90]]

我想使用列表推导,因为我不想通过迭代主列表中的每个内部列表然后使用临时列表添加到它来以正常方式执行此操作。

有什么帮助吗?

【问题讨论】:

  • 你可以通过澄清你的意图来改善这个问题。您声称要使用列表理解附加到每个列表,但您选择了一个创建副本的答案,附加到这些列表而不是您提到的列表。如果这是您想要的,请编辑您的问题以明确说明。

标签: python


【解决方案1】:

您可以使用列表添加来完成此操作:

[l + [90] for l in lists]

【讨论】:

  • 这非常浪费,因为它会创建列表的副本。事实上,它并没有附加每个列表。它创建全新的列表。想象一下 1000x1000 列表的渐近情况。
  • @AryaMcCarthy 是的,这很浪费,但是如果您阅读 OP 的问题,这就是他/她想要的。
【解决方案2】:

方法

原生 Python(@acushner 首先介绍了这个):

lsts = [[1,345,0,304], [0,345,678,946,90], [0,23,3,56,3,5,9,0]]
[lst + [90] for lst in lsts]

或者,itertools.chain:

import itertools as it

[list(it.chain(lst, [90])) for lst in lsts]

为了好玩,第三方库more-itertoolspip install more_itertools):

import more_itertools as mit

[list(mit.padded(lst, fillvalue=90, n=len(lst)+1)) for lst in lsts]

警告

一些答案​​试图在迭代时改变一个列表。虽然这些选项给出了相同的结果,可能更节省内存,甚至对于针对此特定问题的较大数据可能更快,但它们可以说是非 Pythonic 且不推荐的做法。

来自Python docs

有时在循环列表时更改列表很诱人;但是,创建一个新列表通常更简单、更安全。

当迭代列表中的removinginserting 元素时尤其如此。后一种方法采用这种创建新列表的惯例。但是,对于某些无害的circumstances,妥协可能是迭代嵌套列表的副本:

lists = [[1,345,0,304], [0,345,678,946,90], [0,23,3,56,3,5,9,0]]
for lst in lists[:]:
    lst.append(90)
lists

否则,默认使用@acushner 的方法,这是此处讨论的下一个高性能选项。

【讨论】:

  • 这非常浪费,因为它会创建列表的副本。事实上,它并没有附加每个列表。它创建全新的列表。想象一下 1000x1000 列表的渐近情况。
  • 没有复制。创建新列表。这是 Python 中列表推导的有意和常见约定。你有什么建议?
【解决方案3】:

这也有效

lists = [[1,345,0,304],[0,345,678,946,90],[0,23,3,56,3,5,9,0]]
[l.append(90) for l in lists]
print(lists)

[[1, 345, 0, 304, 90], [0, 345, 678, 946, 90, 90], [0, 23, 3, 56, 3, 5, 9, 0, 90]]

【讨论】:

  • 这个解决方案是最好的,因为它改变了数据结构,而不是创建一个新的。话虽如此,这不是您应该使用列表推导的方式。这个问题最好用 for 循环来回答。
  • 你能解释一下为什么不应该使用列表推导吗?
  • @Serjik 这不正确。它不起作用,因为 append 返回 None
  • @Baktaawar 绝对有效,只打印结果,None 是因为 append 没有返回值
  • @Arya McCarthy :作为你的评论最好,为什么任何其他答案都得到了赞成而我得到了反对???
【解决方案4】:

还有一个:

lists = [[1,345,0,304],[0,345,678,946,90],[0,23,3,56,3,5,9,0]]
for _ in map(lambda x: x.append(90), lists):
    pass

【讨论】:

    【解决方案5】:

    另一种选择

    lists = [[1,345,0,304], [0,345,678,946,90], [0,23,3,56,3,5,9,0]]
    
    for lst in lists:
        lst.append(90)
    
    print lists
    [[1, 345, 0, 304, 90],[0, 345, 678, 946, 90, 90],[0, 23, 3, 56, 3, 5, 9, 0, 90]]
    

    【讨论】:

    • 考虑改变嵌套列表的副本(请参阅帖子了解基本原理)。同样为清楚起见,我将交换 lstlists 的名称。否则,这是一个很好的答案。
    • 改变你正在迭代的同一个列表不是最佳实践。在这种情况下,它是无害的,因为您没有删除项目,但更安全的习惯是迭代副本,例如lists[:]。此类帖子有好几篇stackoverflow.com/questions/1637807/…。只需替换for lst in lists[:]:
    • @pylang 他没有要求迭代副本
    • 我在建议一个成语来改善你的答案。有关更多信息,请参阅我发布的警告。谢谢你的帖子。
    猜你喜欢
    • 2023-03-21
    • 2021-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-11
    相关资源
    最近更新 更多