2017-11-11 296 views
0

我正在Python中编写脚本来模拟辩论者的比赛。但我遇到了这个奇怪的错误,看起来像通过引用问题,但有一些行为,不应该通过引用的影响。Python通过引用和字典副本传递

基本上,团队是一个团队字典,每个团队都有一堆领域,包括胜利和失败领域,当我第一次建立团队时,这两个领域都被初始化为0。

然后df.apda_tournament()接收一个团队词典,并根据模拟改变团队的胜负,并返回更新的团队词典。

由于参考作品的传递方式,团队字典被传递到df.apda_tournament()中,并且返回的一个最终都被修改,因为该函数改变了传入字典中记录的胜负,并返回它。因此:

apda_results == apda_teams 

正如我所预期的那样返回True。

奇怪的是,df.apda_tournament()也改变了原始团队字典apda_teams是副本。所以它最终成为:

apda_teams == teams 

也返回true。这很奇怪,因为它看起来像apda_teams,当我声明它只是对团队的引用而不是副本时,我不会指望它,因为我将它声明为函数之外。

有人可以解释到底发生了什么吗?另外我该如何避免这种情况,apda_teams实际上是团队字典的唯一副本,而不仅仅是对内存中记录的引用?

附在下面是代码:

import debate_functions as df 

dbtr_num = 64 
team_num = dbtr_num/2 
dbtr_mn_mn = 200 
dbtr_mn_std = 80 
dbtr_std_mn = 80 
dbtr_std_std = 60 
judge_bias = 70 

dbtrs = df.make_debaters(dbtr_num, dbtr_mn_mn, dbtr_mn_std, dbtr_std_mn, dbtr_std_std) 
teams = df.make_teams(dbtrs, dbtr_mn_mn, dbtr_mn_std) 
print(teams) 
apda_teams = teams 
para_teams = teams 

apda_results = df.apda_tournament(5, apda_teams, judge_bias) 
print('Check this') 
print(apda_results == apda_teams) 
print(apda_teams == teams) 

运行它返回:

Check this 
True 
True 
+0

通过引用或值的概念,Python不能像C一样工作。长话短说:如果你没有明确地复制一本字典,它将在通话和分配中保持相同的对象。 –

+0

是的,我明白了,我特别想知道这个代码中的团队,因为我明确地将它复制到apda_teams,然后只在apda_teams上调用函数,但团队正在修改。 –

回答

0

在Python列表,字典是可变的,(我们可以修改的内容)。所以,无论何时您将列表,字典传递给任何函数或分配给任何变量,都会指向给定变量的引用。

字符串,数字,元组是不可变的(我们不能修改内容)。所以,只要你字符串元组,数字到任何函数或分配给任何变量,那么它只是复制值。

+0

是的,我明白了,这就是为什么(apda_results == apda_teams)评估为True。我想知道的是为什么(apda_teams ==队)也评估为真,当apda_teams是一个球队的副本,然后在传递给一个函数时被修改。现在团队也被apda_teams传递给函数所改变,即使团队永远不会通过任何函数。 –

+0

对于延迟抱歉,apda_teams =队(与参考相同的赋值),您需要像apda_teams = dict(队)或列表apda_teams = list(队)一样执行深度拷贝。 –