If you're seeing the list values change, it's likely that your function is always returning the same list
object, not separate lists on separate times. Even if you kept the lists outside of the dictionary you're merging, you'd find the old ones didn't have the same values in them you expected.
You can see that kind of behavior with this code:
_lst = [] # this is an implementation detail of the function below
def foo():
"""returns a steadily longer list of "foo" strings"""
_lst.append('foo')
return _lst
print(foo()) # prints ['foo']
print(foo()) # prints ['foo', 'foo'], all as expected so far
x = foo()
print(x) # prints ['foo', 'foo', 'foo'], fine
y = foo()
print(y) # prints ['foo', 'foo', 'foo', foo'], fine here too
print(x) # prints ['foo', 'foo', 'foo', foo'], unexpectedly changed!
You might be surprised how the value of x
changed when foo
was called again to assign y
. But that's only if you don't realize that x
and y
are both references to the same list object _lst
(something you might not know if you don't know how the foo
function is implemented).
In your code, your function is returning the same list in the same way that foo
is (though with a dictionary wrapped around it, so it's less obvious). If you control the function, you might be able to change it so that it returns a new list each time. In my example, that might look like:
def foo():
_lst.append('foo')
return list(_lst) # return a shallow copy of the list!
Your code would probably be a bit more complicated, but probably not by much. Just make sure you make a new list for each dictionary you return.
On the other hand, if you can't modify the function (perhaps because it's part of a library or something), you can instead make the copy yourself, when you go to merge the dictionaries.
finaldict = dict()
while some_condition():
dict1 = function_call()
finaldict.update((key, list(value)) for key, value in dict1.items())
The generator expression we're passing to dict.update
yields key, value
tuples, but the values are shallow copies of the lists in the dictionary we got from function_call
.