0

My goal is to build a dictionary in Python. My code seems to work. However, when I attempt to append a value to a single key the value is appended to multiple keys. I understand this is because the fromkeys method assigns multiple keys to the same list. How do I create multiple keys from a list with each assigned to a unique array?

#Create an Array with future dictionary keys
x = ('key1', 'key2', 'key3')

#Create a Dictionary from the array

myDict = dict.fromkeys(x,[])

#Add some new Dictionary Keys
myDict['TOTAL'] = []

myDict['EVENT'] = []



#add an element to the Dictionary works as expected

myDict['TOTAL'].append('TOTAL')

print(myDict)

#{'key1': [], 'key2': [], 'key3': [], 'TOTAL': ['TOTAL'], 'EVENT': []}



#add another element to the Dictionary
#appending data to a key from the x Array sees the data appended to all the keys from the x array
myDict['key1'].append('Entry')

print(myDict)

#{'key1': ['Entry'], 'key2': ['Entry'], 'key3': ['Entry'], 'TOTAL': ['TOTAL'], 'EVENT':
# []}
  • 2
    You're confusing reference and value. Each one of those dictionary keys is pointing at the *same* list. `myDict = dict.fromkeys([(key, []) for key in x])` – Jared Smith Aug 11 '20 at 17:16
  • 1
    Does this answer your question? [Python -- by value vs by reference](https://stackoverflow.com/questions/31603720/python-by-value-vs-by-reference) – Jared Smith Aug 11 '20 at 17:19
  • I see what you are saying and appreciate it. How do I create my dictionary such that each key points to a unique list? – Matthew David Jankowski Aug 11 '20 at 17:24

2 Answers2

1

Key1, key2, and key3 all contain a reference to a single list, which you are appending to. They don't each include a unique list.

Jared's answer above is correct. You can also write:

myDict = dict()
for key in x:
  myDict[key] = []

which does the same thing.

  • I think you have it. How would I create the dictionary so that each key would reference a unique list? – Matthew David Jankowski Aug 11 '20 at 17:19
  • 1
    @MatthewDavidJankowski see my comment on your question. – Jared Smith Aug 11 '20 at 17:20
  • 1
    Yup, Jared Smith answered it first. If you're new (like me), list comprehensions can be hard to parse. I'll edit my answer with the 'long' version. – Brenton Haerr Aug 11 '20 at 17:25
  • Will wait a bit to see if someone has a more elegant way to do what I need to do. If no one replies I'll accept this as the answer. Your answer did help me quite a bit. Thanks! – Matthew David Jankowski Aug 11 '20 at 18:12
  • In your answer below, you don't need the tempdict step. You don't have to create a dict using fromkeys. You can just assign a key using a string. `myDict['key1'] = []` will create that key and assign it an empty list as a value. Also, I couldn't quite tell from your question, but you do know you don't have to have a list in a dictionary value, right? `myDict['total'] = 1000` works too. Feel free to disregard if you knew that but just wanted everything in a nested list for this use, of course. – Brenton Haerr Aug 11 '20 at 18:37
  • @BrentonH My program needs to be written assuming it doesn't know the number and names of keys beforehand. Instead, it reads in the keys from a large CSV. Hence the need to work from a list. My confusion was the keys created from the array all pointed to the same list. You cleared that up for me – Matthew David Jankowski Aug 11 '20 at 19:30
  • Hi Matthew, yes, I understand that. I just meant that each dictionary key does not have to contain a list. `myDict['TOTAL']` seems like an odd key to contain a list. I would think it would usually just contain a value. Ie, `myDict['total'] = 1000` vs `myDict['total'] = [1000]`. That way you don't have to be appending/popping values every time. You can just assign values to keys. – Brenton Haerr Aug 11 '20 at 20:34
  • @BrentonH I get what you are saying. In this case total is the row total. That is why I made it an array. Thanks for your input!. It would be better named 'ROW_TOTAL' – Matthew David Jankowski Aug 13 '20 at 00:53
0

Based on the answers so far I cobbled together an approach that works. Is this the 'python' or 'python optimal' way to do this?

#Create an Array with future dictionary keys
x = ('key1', 'key2', 'key3')


#Create a Dictionary from the array

tempDict = dict.fromkeys(x,[])


myDict = {}



for key in tempDict.keys():
    
    print(key)
    
    myDict[key] = []


#Add some new Dictionary Keys

myDict['TOTAL'] = []

myDict['EVENT'] = []

print(myDict)


#add an element to the Dictionary works as expected   
myDict['TOTAL'].append('TOTAL')
print(myDict)
#{'key1': [], 'key2': [], 'key3': [], 'TOTAL': ['TOTAL'], 'EVENT': []}



#add another element to the Dictionary
#appending data to a key from the x  Array sees the data appended to all the x keys.
myDict['key1'].append('Entry') 
print(myDict)

#{'key1': ['Entry'], 'key2': [], 'key3': [], 'TOTAL': ['TOTAL'], 'EVENT':
# []}