变量覆盖在函数内部

时间:2017-07-25 20:47:36

标签: python python-2.7

我在Python 2.7中有以下代码

abc=[[1,2,3],[0,1,2]]
def make_change(some_list):
    for i in range(len(some_list)):
        if some_list[i][0]==0:
            some_list[i]=[]
    return some_list

new_list=make_change(abc)

print abc
print new_list

我的理解是它应该产生以下输出。

[[1,2,3],[0,1,2]]

[[1,2,3],[]]

但是python实际上产生了

[[1,2,3],[]] 

[[1,2,3],[]]

我错过了什么吗?

3 个答案:

答案 0 :(得分:2)

您可以通过在将列表传递给函数时复制列表来防止此问题:

abc=[[1,2,3],[0,1,2]]
def make_change(some_list):
    for i in range(len(some_list)):
        if some_list[i][0]==0:
            some_list[i]=[]
    return some_list

new_list=make_change(abc[:])

print abc
print new_list

改变的部分:

new_list=make_change(abc[:])

发生这种情况的原因是Python通过引用传递列表,因此也会对原始列表进行更改。使用[:]创建一个浅拷贝,这足以防止这种情况。

答案 1 :(得分:0)

除非您特别希望该功能更改传递给它的列表,否则请勿更改传递给函数的列表。制作列表(或任何其他可变对象)的副本并处理副本。如果您正在使用复合对象(包含对象的对象),请使用copy.deepcopy确保所有内容都是副本。

由于存在函数来封装你必须做的奇怪的东西,对你传递给函数的对象做奇怪的东西很少对我有意义。另一个答案是您将列表的切片副本传递给函数。为什么不通过将mutable传递给函数并让函数创建副本来使整个事物更具可读性。更好的封装=更少恼人的代码。

abc=[[1,2,3],[0,1,2]]
def make_change(some_list):
    from copy import deepcopy
    new_list = deepcopy(some_list)
    for i in range(len(new_list)):
        if new_list[i][0]==0:
            new_list[i]=[]
    return new_list

new_list=make_change(abc)

print abc
print new_list

答案 2 :(得分:0)

列出对救援的理解!

abc=[[1,2,3],[0,1,2]]

def make_change(some_list):
    return [[] if a[0]==0 else a for a in some_list]

make_change(abc)
[[1, 2, 3], []]