奇怪的python指令分配

奇怪的python指令分配,python,dictionary,Python,Dictionary,今天早上我遇到了一个奇怪的问题: >>> l = ['a', 'b', 'c'] >>> dict = dict.fromkeys(l, []) >>> dict['a'] += [1] >>> dict {'a': [1], 'c': [1], 'b': [1]} 我无法解释为什么会发生这种情况?dict.fromkeys创建了对同一列表的大量引用。换句话说,d['a']是d['b']等。当您执行+=操作时,您会在适当的

今天早上我遇到了一个奇怪的问题:

>>> l = ['a', 'b', 'c']
>>> dict = dict.fromkeys(l, [])
>>> dict['a'] += [1]
>>> dict
{'a': [1], 'c': [1], 'b': [1]}

我无法解释为什么会发生这种情况?

dict.fromkeys创建了对同一列表的大量引用。换句话说,
d['a']
d['b']
等。当您执行
+=
操作时,您会在适当的位置扩展列表,因此在所有列表中都可以看到修改——毕竟,它们是相同的列表

>>> l = ['a', 'b', 'c']
>>> d = dict.fromkeys(l, [])
>>> d
{'a': [], 'c': [], 'b': []}
>>> print [id(v) for v in d.values()]  # Note, they all have the same ID -- They're the same.
[4385936016, 4385936016, 4385936016]
>>> d['a'] += [1]
>>> d
{'a': [1], 'c': [1], 'b': [1]}

正如评论中指出的,我并没有告诉你如何解决这个问题。如果要使用作为可变值实例的键初始化字典,可以使用字典理解:

d = {key: [] for key in l}
或者,如果您使用的是旧版本的python(在python2.7之前),则将生成2元组的iterable传递给dict构造函数:

d = dict((key, []) for key in l)

请注意,还需要了解其他一些变体(
colections.defaultdict
,一个覆盖了
\uuu缺少\uuu
的常规dict子类)。我所解释的每一种行为都略有不同。但是,这应该足以让您暂时开始…

dict.fromkeys创建对同一列表的大量引用。换句话说,
d['a']
d['b']
等。当您执行
+=
操作时,您会在适当的位置扩展列表,因此在所有列表中都可以看到修改——毕竟,它们是相同的列表

>>> l = ['a', 'b', 'c']
>>> d = dict.fromkeys(l, [])
>>> d
{'a': [], 'c': [], 'b': []}
>>> print [id(v) for v in d.values()]  # Note, they all have the same ID -- They're the same.
[4385936016, 4385936016, 4385936016]
>>> d['a'] += [1]
>>> d
{'a': [1], 'c': [1], 'b': [1]}

正如评论中指出的,我并没有告诉你如何解决这个问题。如果要使用作为可变值实例的键初始化字典,可以使用字典理解:

d = {key: [] for key in l}
或者,如果您使用的是旧版本的python(在python2.7之前),则将生成2元组的iterable传递给dict构造函数:

d = dict((key, []) for key in l)

请注意,还需要了解其他一些变体(
colections.defaultdict
,一个覆盖了
\uuu缺少\uuu
的常规dict子类)。我所解释的每一种行为都略有不同。但是,这应该足以让您暂时开始……

您可能对集合感兴趣。defaultdict:

In [66]: d = collections.defaultdict(list)

In [67]: d['a'] += [1]

In [68]: d
Out[68]: defaultdict(<class 'list'>, {'a': [1]})

In [69]: dict(d)
Out[69]: {'a': [1]}

In [70]: d['b']
Out[70]: []

In [71]: dict(d)
Out[71]: {'b': [], 'a': [1]}

In [72]: d['c']
Out[72]: []

In [73]: dict(d)
Out[73]: {'b': [], 'c': [], 'a': [1]}
[66]中的
:d=collections.defaultdict(列表)
在[67]中:d['a']+=[1]
In[68]:d
Out[68]:defaultdict(,{'a':[1]})
在[69]中:dict(d)
Out[69]:{'a':[1]}
在[70]中:d['b']
出[70]:[]
在[71]中:dict(d)
Out[71]:{b':[],'a':[1]}
In[72]:d['c']
出[72]:[]
在[73]中:dict(d)
Out[73]:{b':[],'c':[],'a':[1]}

您可能对collections感兴趣。defaultdict:

In [66]: d = collections.defaultdict(list)

In [67]: d['a'] += [1]

In [68]: d
Out[68]: defaultdict(<class 'list'>, {'a': [1]})

In [69]: dict(d)
Out[69]: {'a': [1]}

In [70]: d['b']
Out[70]: []

In [71]: dict(d)
Out[71]: {'b': [], 'a': [1]}

In [72]: d['c']
Out[72]: []

In [73]: dict(d)
Out[73]: {'b': [], 'c': [], 'a': [1]}
[66]中的
:d=collections.defaultdict(列表)
在[67]中:d['a']+=[1]
In[68]:d
Out[68]:defaultdict(,{'a':[1]})
在[69]中:dict(d)
Out[69]:{'a':[1]}
在[70]中:d['b']
出[70]:[]
在[71]中:dict(d)
Out[71]:{b':[],'a':[1]}
In[72]:d['c']
出[72]:[]
在[73]中:dict(d)
Out[73]:{b':[],'c':[],'a':[1]}

我认为您没有发布您实际使用的代码。对不起,我使用了dict.fromkeys函数,我想我正在关闭ReasonWhat版本的python?@IgnacioVazquez Abrams——不能复制吗?我可以。。。python2.7和python3.2在OS-X上。@mgilson:OP编辑了这个问题,但它在5分钟的宽限期内,所以它没有显示为编辑。我认为你没有发布你实际使用的代码。对不起,我使用了dict.fromkeys函数,我想我正在关闭reasonWhich版本的python?@IgnacioVazquez Abrams--不能复制?我可以。。。python2.7和python3.2在OS-X上。@mgilson:OP编辑了这个问题,但它在5分钟的宽限期内,所以它没有显示为编辑。海报试图做的正确标记是
dict={key:[]for key in l}
,给每个键一个唯一的列表,我不想在你已经确定答案的情况下发布新答案。@user2085282——说得好。我想我应该提供一个替代方案。海报试图做的正确标记是
dict={key:[]for key in l}
,给每个键一个唯一的列表,我不想在你已经确定答案的情况下发布一个新的答案。@user2085282——很好。我想我应该提供一个替代方案。