对于我的生活,我无法弄清楚为什么会发生以下情况:
x = 2
y = []
z = { "player" : 0, "name": "none", "fired": 0, "hits": 0, "misses": 0, "streak": 0, "longest streak": 0 }
def number_player(x, y, z):
for i in range(x):
y.append(z)
y[i]["player"] = (i + 1)
number_player(x, y, z)
print y
控制台返回:
[{'streak': 0, 'hits': 0, 'name': 'none', 'player': 2, 'misses': 0, 'longest streak': 0, 'fired': 0}, {'streak': 0, 'hits': 0, 'name': 'none', 'player': 2, 'misses': 0, 'longest streak': 0, 'fired': 0}]
简而言之,它会创建一个{...“播放器”:“2”......}的键/值对两次。如果我在每个循环结束时请求打印,则列表中第一个返回的字典包含{...“播放器”:“1”...}按预期的键/值对。
对我来说,如果我通过,那么陌生人仍然是:
x = 3
y = [{ "player" : 0, "name": "none", "fired": 0, "hits": 0, "misses": 0, "streak": 0, "longest streak": 0 }]
然后运行for循环,所以它附加了两个词典,循环在第一个上运行正常,然后复制最后两个的值。我认为这里的原因和决心是存在的,尽管我对这个问题太新了,无法从问题中辨别出来。
让我理解为什么会发生这种情况的帮助将不胜感激。
谢谢
答案 0 :(得分:3)
您混淆的原因是第y.append(z)
行。
这不附加字典z
的副本,而是附加z
的同一个实例的另一个引用。
因此,在修改刚刚附加的字典的循环的最后一次迭代中,您还要修改在上一次迭代中附加的第一个字典。您的列表y
实际上只是[z, z]
。
>>> print y
[{'streak': 0, 'hits': 0, 'name': 'none', 'player': 2, 'misses': 0, 'longest streak': 0, 'fired': 0}, {'streak': 0, 'hits': 0, 'name': 'none', 'player': 2, 'misses': 0, 'longest streak': 0, 'fired': 0}]
>>> y[0]
{'fired': 0,
'hits': 0,
'longest streak': 0,
'misses': 0,
'name': 'none',
'player': 2,
'streak': 0}
>>> y[0] is y[1]
True
>>> y[0]['player'] = 123
>>> y[1]['player']
123
创建结构的更加pythonic的方法是使用列表理解:
>>> def new_player(n, name="none"):
... return {"player" : n, "name": name, "fired": 0, "hits": 0, "misses": 0, "streak": 0, "longest streak": 0}
...
>>> y = [new_player(n) for n in range(2)]
>>> y
[{'fired': 0,
'hits': 0,
'longest streak': 0,
'misses': 0,
'name': 'none',
'player': 0,
'streak': 0},
{'fired': 0,
'hits': 0,
'longest streak': 0,
'misses': 0,
'name': 'none',
'player': 1,
'streak': 0}]
答案 1 :(得分:1)
正如其他人所指出的那样,你将对同一个dictionairy的引用附加
从复制模块中使用deepcopy。
import copy
x = 2
y = []
z = { "player" : 0, "name": "none", "fired": 0, "hits": 0, "misses": 0, "streak": 0, "longest streak": 0 }
def number_player(x, y, z):
for i in range(x):
y.append(copy.deepcopy(z))
y[i]["player"] = (i + 1)
number_player(x, y, z)
print y