Can't create list of dictionaries

S

sophie_newbie

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!
 
S

sophie_newbie

Scratch everything I said, copy() does work. Made a wee mistake
somewhere else.

Apologies if I've wasted anyones time!
 
J

John Machin

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!

Do you mean that the length of the list is 1, or do you mean that the
same dictionary has been appended 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.

I think you had better show us your code, and the output from (say) 3
iterations (not 1000!!). If you are really doing "list.append
(functThatReturnsDict())" all in one line, break it up into multiple
lines so that some print statements can be used for debugging:

adict = functThatReturnsDict()
print "A", id(adict), len(adict), adict
alist.append(adict)
print "B", len(alist), id(alist[-1])

Clean it up a bit ... the dict.copy() is extremely unlikely to be part
of a principled solution, so remove any trace of that.

Cheers,
John
 
J

John Machin

Scratch everything I said, copy() does work. Made a wee mistake
somewhere else.

Apologies if I've wasted anyones time!

Ummmm ... if think you need a dict.copy() *after* the function has
returned, then you are likely to be doing it in a way that perhaps you
shouldn't make a habit of :)
 
P

Peter Otten

sophie_newbie said:
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
 
P

Piet van Oostrum

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

You better post some real code.
 
G

Gabriel Genellina

Scratch everything I said, copy() does work. Made a wee mistake
somewhere else.

If the function is supposed to return a *different* dictionary each time,
ensure that, don't "fix" the result value after it has returned.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top