Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Appending to one python dictionary key appends to all for some reason

This is my python code (I am using Python 2.7.6):

row_of_words = ['word 1', 'word 2']
hw = ['h1', 'h2']
TD = {}

TD = TD.fromkeys(hw, [])
# TD is now {'h1': [], 'h2': []}

for index in range(len(row_of_words)):
    # This loops twice and in the first loop, index = 0 and in the second
    # loop, index = 1

    # Append 1 to the value of 'h1' (which is a list [])
    # The value for 'h1' should now be [1].

    # This loops twice to append 1 twice to the value of 'h1'.
    TD['h1'].append(1)

>>>TD
{'h2': [1, 1], 'h1': [1, 1]}

As you can see in the two lines right above, when I print TD, it shows that the 1 was appended to both h1 and h2. Any idea why it was appended to both even though I mentioned to only append it to TD['h1']? How do I make it so that it only appends to the value of 'h1'? I commented my steps showing how I think it works.

like image 825
SilentDev Avatar asked Feb 08 '23 10:02

SilentDev


2 Answers

Continuing on with my comment, you can use a dict comprehension:

TD = {key:[] for key in hw}

would create an empty list for each item in hw. For example:

>>> hw = ['h1','h2']
>>> TD = {key:[] for key in hw}
>>> TD
{'h1': [], 'h2': []}
>>> TD['h1'].append(1)
>>> TD
{'h1': [1], 'h2': []}

To answer your original question:

The reason that changing one list would have changed every list is because dict.fromkey(seq,[value]) is a function that creates a new dictionary where every item in seq will map to the optional argument value. You passed in an empty list as value which means that you set each key to point to a reference to the same list. Since all the keys point to the same list, then obviously changing the list by accessing ANY key (try accessing h2 and you will see this is true) will reflect that change across all keys.

like image 116
R Nar Avatar answered Feb 12 '23 11:02

R Nar


You can do this:

TD = dict((i, [],) for i in hw)
like image 45
sisanared Avatar answered Feb 12 '23 11:02

sisanared