Python从内部函数更改外部字典

Python从内部函数更改外部字典,python,pointers,dictionary,copy,Python,Pointers,Dictionary,Copy,据我所知,我正在经历一种在Python中很常见的行为,但我想知道这是默认行为,以及如何防止这种行为。考虑下面的代码: dic1 = {'a':1, 'b':2} lis1 = [1, 2] def somefunc(dic): dic.update({'b':20}) return dic def otherfunc(lis): lis.append(20) return lis for i in range(3): dic2 = dic1

据我所知,我正在经历一种在Python中很常见的行为,但我想知道这是默认行为,以及如何防止这种行为。考虑下面的代码:

dic1 = {'a':1, 'b':2}
lis1 = [1, 2]

def somefunc(dic):
    dic.update({'b':20})
    return dic

def otherfunc(lis):
    lis.append(20)
    return lis

for i in range(3):
    dic2 = dic1
    lis2 = lis1
    print(dic2)
    somefunc(dic2)
    print(lis2)
    otherfunc(lis2)
我们运行这个代码,它输出

{'a': 1, 'b': 2}
[1, 2]
{'a': 1, 'b': 20}
[1, 2, 20]
{'a': 1, 'b': 20}
[1, 2, 20, 20]
但是为什么它不输出以下内容呢

{'a': 1, 'b': 2}
[1, 2]
{'a': 1, 'b': 2}
[1, 2]
{'a': 1, 'b': 2}
[1, 2]
我觉得它应该输出这个,因为我正在重置
dic2
lis2
。为什么这是默认行为?Python进入函数后不应该复制dic2吗?
dic2=dic1
不应该创建dic1的副本,而应该创建指向内存中同一位置的不同指针吗?(如果真是这样的话)

我可以通过将
dic2=dic1
替换为
dic2=dic1.copy()
(或将
dic=dic.copy()
添加到函数中)来防止这种行为在
dic1
中发生,但如何使用列表?他们没有复制方法。此外,在默认情况下,是否有一种方法可以防止这种情况发生,而不必在每次处理函数中的字典(甚至数据帧等)时都记住使用copy方法


在Python上,列表是可变的,这意味着lis2只是lis1的另一个名称,因此它们是相同的对象

以下是在lis2上复制lis1的两种方法:

lis2 = lis1[:]

lis2 = list(lis1)

我更喜欢使用
list()
,因为它更具可读性。

Python中的所有值都是通过引用传递的。有关更完整的解释,请参见此。