Can't create list of dictionaries

Peter Otten __peter__ at web.de
Fri Apr 10 08:02:01 EDT 2009


sophie_newbie wrote:

> Hi there,
> 
> I've got a function that returns a dictionary, I need to loop and
> return 1000 dictionaries and append them to a list, but the thing is
> that when I do the list.append(funtThatReturnsDict()) the resulting
> only ever has 1 dictionary attached to it, even after running the
> append function 1000 times!
> 
> I've tried using dict.copy() on the dictionary that was returned from
> the function but this didn't work either.
> 
> And the function is definately returning different dictionaries each
> time as I can see that when I print them.
> 
> I know this is something to do with the dictionries being stored as
> references but I've no idea how to fix it seeing as the copy()
> function didn't work.
> 
> Thanks!

Let's see. First, a function that returns a new dictionary on every run:

>>> def new_dict(): return {}
...
>>> dicts = [new_dict() for _ in range(3)]
>>> dicts
[{}, {}, {}]
>>> dicts[1]["x"] = 42
>>> dicts
[{}, {'x': 42}, {}]

Works. Now a function that always returns the same dictionary:

>>> def same_dict(d={}): return d
...
>>> dicts = [same_dict() for _ in range(3)]
>>> dicts
[{}, {}, {}]
>>> dicts[1]["x"] = 42
>>> dicts
[{'x': 42}, {'x': 42}, {'x': 42}]

That's not what we want. Can it be fixed with dict.copy()?

>>> dicts = [same_dict().copy() for _ in range(3)]
>>> dicts
[{'x': 42}, {'x': 42}, {'x': 42}]

Hm, it wasn't a good idea to reuse same_dict() from the previous example
because the default value was changed by the 

dicts[1]["x"] = 42

statement. Second try:

>>> def same_dict(d={}): return d
...
>>> dicts = [same_dict().copy() for _ in range(3)]
>>> dicts
[{}, {}, {}]
>>> dicts[1]["x"] = 42
>>> dicts
[{}, {'x': 42}, {}]

So the approach using dict.copy() works, too. 

Note however, that you ust make a deep copy if you have mutable values

>>> d = dict(a=[])
>>> e = d.copy()
>>> d["a"].append(42)
>>> d
{'a': [42]}
>>> e
{'a': [42]}

>>> import copy
>>> d = dict(a=[])
>>> e = copy.deepcopy(d)
>>> d["a"].append(42)
>>> d
{'a': [42]}
>>> e
{'a': []}

Peter



More information about the Python-list mailing list