Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python for loop appending to every key in dictionary

I'm iterating over a list of tuples and a list of strings. The strings are identifiers for the items in the list. I have a dictionary that has the strings identifiers as keys and has an initially empty list for each value. I want to append something from the tuple list to each key. A simplified version of what I'm doing is:

tupleList = [("A","a"),("B","b")]
stringList = ["Alpha", "Beta"]
dictionary = dict.fromkeys(stringList, [])  # dictionary = {'Alpha': [], 'Beta': []}
for (uppercase, lowercase), string in zip(tupleList, stringList):
    dictionary[string].append(lowercase)

I would expect this to give dictionary = {'Alpha': ['a'], 'Beta': ['b']}, but instead I find that {'Alpha': ['a', 'b'], 'Beta': ['a', 'b']}. Does anyone have any idea what I'm doing wrong?

like image 417
Ben Bartlett Avatar asked May 10 '26 11:05

Ben Bartlett


1 Answers

Your problem is that you share the list between the two keys by reference.

What happens is that dict.fromkeys doesn't create a new list for each key, but gives the reference to the same list to all the keys. the rest of your code looks correct :)

Instead of doing that you should use a defaultdict, basically it is a dict, which creates new values if they don't exist, and retrieves them if they do (and removes the need for the if / else when inserting an item to check if it already exists). It's really useful in these kinds of situations:

from collections import defaultdict

tupleList = [("A","a"),("B","b")]
stringList = ["Alpha", "Beta"]
dictionary = defaultdict(list) # Changed line
for (uppercase, lowercase), string in zip(tupleList, stringList):
    dictionary[string].append(lowercase)
like image 80
Ehud Halamish Avatar answered May 13 '26 00:05

Ehud Halamish



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!