问题
I have a dictionary of empty lists with all keys declared at the beginning:
>>> keys = ["k1", "k2", "k3"]
>>> d = dict.fromkeys(keys, [])
>>> d
{'k2': [], 'k3': [], 'k1': []}
When I try to add a coordinate pair (the list ["x1", "y1"]
) to one of the key's lists, it instead adds to all the keys' lists:
>>> d["k1"].append(["x1", "y1"])
>>> d
{'k1': [['x1', 'y1']], 'k2': [['x1', 'y1']], 'k3': [['x1', 'y1']]}
What I was looking for was:
>>> d
{'k1': [['x1', 'y1']], 'k3': [], 'k1': []}
How can I achieve this in Python 3?
回答1:
Looks like each of those lists is actually a reference to a single list. Appending to one of them appends to all of them.
I don't think you can work around this while still using fromkeys
. Try using a dict comprehension instead.
d = {k: [] for k in keys}
回答2:
Create your dictionary like this:
d = {k: [] for k in keys}
dict.fromkeys()
puts a reference to the same list as value for all keys into the dictionary.
You can visualize this by looking at the id
of your values:
>>> d = dict.fromkeys(keys,[])
>>> [id(v) for v in d.values()]
[4413495432, 4413495432, 4413495432]
Because the id
uniquely identifies an object, this means you have the same object three times.
回答3:
The fromkeys
is a class method which passes the second argument as the value for all of the keys, thus they all would reference to one object. instead you if you don't pass the value python will consider the None as the value for each item. Then instead of append you can assign a 2d list to your key:
>>> d = dict.fromkeys(keys)
>>> d["k1"] = [["x1", "y1"]]
>>> d
{'k3': None, 'k2': None, 'k1': [['x1', 'y1']]}
This is how python has created the fromkeys
method:
@classmethod
def fromkeys(cls, iterable, value=None):
d = cls()
for key in iterable:
d[key] = value
return d
来源:https://stackoverflow.com/questions/35093815/appending-to-dict-of-lists-adds-value-to-every-key