【问题标题】:How to clone a nested list in Python?如何在 Python 中克隆嵌套列表?
【发布时间】:2012-08-12 10:40:02
【问题描述】:

我正在阅读“如何像计算机科学家一样思考:使用 Python 第 2 版文档学习”。在Chapter 9 的末尾有这个练习 11,它要求你 编写 Python 代码使 doctest 通过。

我的初步解决方案:

def add_column(matrix):
"""
  >>> m = [[0, 0], [0, 0]]
  >>> add_column(m)
  [[0, 0, 0], [0, 0, 0]]
  >>> n = [[3, 2], [5, 1], [4, 7]]
  >>> add_column(n)
  [[3, 2, 0], [5, 1, 0], [4, 7, 0]]
  >>> n
  [[3, 2], [5, 1], [4, 7]]
"""
result = matrix[:]
for index in range(len(matrix)):
    result[index] += [0]
return result


if __name__ == "__main__":
    import doctest
    doctest.testmod()

但是,这段代码没有通过第二次测试。我将 for 循环的主体更改为以下内容:

result[index] = result[index] + [0]

现在代码通过了所有测试。但我不明白代码中的这种变化是如何解决问题的。我以为result[index] = result[index] + [0]result[0] += [0] 的显式形式,那为什么行为不一样呢?

将我的答案与解决方案中提供的代码进行比较后,我怀疑问题可能在于我如何克隆列表。在解决方案中,它是这样完成的:result = [d[:] for d in matrix],在这种情况下,我的初始 for 循环将起作用。但是为什么result = matrix[:] 不起作用?它是在创建别名,而不是新对象吗?

另外,有人能解释一下[d[:] for d in matrix] 是如何解析的以及何时使用这种语法吗?我以前没有见过这种使用 for 循环的方式,并且在课程中也没有解释/演示过。

【问题讨论】:

    标签: list for-loop python-2.7 clone


    【解决方案1】:

    该列表没有被克隆,原因如下:

    result = matrix[:]
    

    确实复制了列表;但您还没有复制列表items。 Python 通过引用处理列表项,因此 result[0]matrix[0] 仍将指向同一个列表对象,即使 resultmatrix 是不同的列表。

    [d[:] for d in matrix] 会克隆主列表和列表元素,因为它会迭代 matrix 并在新列表中创建每个元素的副本(而不是使用对该元素的引用)。

    您还可以使用copy 模块,该模块特别有用,因为它也可以处理字典,并且使用copy.deepcopy 您可以克隆未知深度的多维列表:http://docspy2zh.readthedocs.org/en/latest/library/copy.html(但如果这样做就足够公平了)超出了您在此处尝试学习的范围)。

    至于'+='和'= ... + ...'之间的区别,我承认我也有点惊讶。在这种情况下,我倾向于使用result[index].append(0),这样可以避免这种歧义;但这当然不是答案。

    【讨论】:

      猜你喜欢
      • 2011-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-21
      • 2010-09-08
      • 2010-09-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多