为什么我的函数会改变参数,即使我把它写成纯函数?

时间:2014-07-14 21:47:35

标签: python python-2.7

此功能为列表中的每个项目添加零。

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]]
"""
    new_list=matrix[:]
    for i in range(len(new_list)):
        new_list[i].append(0)
    return new_list

它改变了我传递的参数,而不是创建它的新对象。 我如何做到这一点,以便我得到预期的结果?

>>> n = [[3, 2], [5, 1], [4, 7]]
>>> g = add_column(n)

预期:

>>> print n
[[3, 2], [5, 1], [4, 7]]

>>> print g
[[3, 2, 0], [5, 1, 0], [4, 7, 0]]

实际结果:

>>> print n
[[3, 2, 0], [5, 1, 0], [4, 7, 0]]

>>> print g
[[3, 2, 0], [5, 1, 0], [4, 7, 0]]

2 个答案:

答案 0 :(得分:5)

[:]仅创建列表的副本。您需要使用copy.deepcopy并创建深层副本:

from copy import deepcopy

def add_column(matrix):  
...
    new_list=deepcopy(matrix)

有关更多信息,请参阅object copying上的这篇维基百科文章。

答案 1 :(得分:1)

您正试图通过使用new_list=matrix[:]复制矩阵来创建纯函数。但是,这只会产生浅拷贝,因此每个子列表仍然是对原始矩阵中相应子列表的引用。可以避免这种情况的一种方法是将行new_list[i].append(0)替换为new_list[i] = new_list[i] + [0],这将生成内部列表的副本。

但是,使用列表推导更简单地解决了这个问题,列表推导会自动创建一个新列表:

def add_column(matrix):
    return [sublist+[0] for sublist in matrix]