Home > Software engineering >  Dictionary updating all keys with nested values
Dictionary updating all keys with nested values

Time:10-23

I am attempting replace values at an index of a nested list inside a dictionary. The dictionary looks like this.

ratings ={'Bill': [0,0,0,0,0,0], 'Sal': [0,0,0,0,0,0], 'Pam': [0,0,0,0,0,0]}

I am building a function that passes in a key. This function should loop through the dictionary to find the key passed in. Then it should update the value of the passed in index reference to the passed in rate parameter.

Instead of updating the passed in key/value list pair its updating every key/(nested)value pair.

I need it to only update the key/value pair that was passed to the function.

Below is the code

key passed in was Bill
index passed in was 2
rate passed in wad 3

def ratingUpdate(key, index, rate, ratings):
        for k in ratings.keys():
          if key == k:
             ratings[key][index]=rate
             break

          else:
            continue
    
Output Expected: 'Bill': [0,0,3,0,0,0], 'Sal': [0,0,0,0,0,0], 'Pam': [0,0,0,0,0,0]

Output Actual: 'Bill': [0,0,3,0,0,0], 'Sal': [0,0,3,0,0,0], 'Pam': [0,0,3,0,0,0]

The dictionary was constructed as follows

users is a set

zeroRaitings is a list of ints

ratingsDict = dict.fromkeys(users, zeroRaitings)

This is function is being used to parse a file to update the ratingsDict

f = open('sample.txt', "r")
    the_file = f.readlines()

for line in range(0, len(the_file)-1, 3):
    key = the_file[line].rstrip()
    #books is a secondary list where the index comes from
    index = books.index(the_file[line 1].rstrip())
    
    rate = int(the_file[line 2].rstrip())
    ratingUpdate(key, index, rate, ratingsDict)
  

CodePudding user response:

You don't need to iterate over the keys a dict to find the corresponding value.

def ratingUpdate(key, index, rate, ratings):
    ratings[key][index]=rate

See also the documentation on dicts: https://docs.python.org/3/tutorial/datastructures.html#dictionaries

As to why every list is being updated, we need to see more of the code to determine. Most likely, every entry on the dict is pointing to the same list instead of each having a different one.

CodePudding user response:

If you created your dictionary the same way you posted it in the question, then it should work as you expect (i.e. lists are independent).

However if you used the same list instance for all keys, all your keys are pointing to the same list content and that's when you get the behaviour you are observing.

For example:

ratings = dict.fromkeys(['Bill','Sal','Pam'],[0,0,0,0,0,0])

would associate the same list to all the keys.

You can check if they are all the same list by printing their id:

print(*map(id,ratings.values()))

If they are all the same, then your keys are all pointing to the same list instance, but the result you are getting pretty much guarantees that this is the case.

CodePudding user response:

You have created your dictionary with your values referencing the same list.

Presumably, you've done this;

inputs = [0, 0, 0, 0, 0, 0]
same_list = {'Bill': inputs, 'Sal': inputs, 'Pam': inputs}

You need to create your ratings dictionary without referencing the same list.

different_list = {'Bill': [0, 0, 0, 0, 0, 0], 'Sal': [0, 0, 0, 0, 0, 0], 'Pam': [0, 0, 0, 0, 0, 0]}

Here is an example to help you understand a little bit better

inputs = [0, 0, 0, 0, 0, 0]

# All your values point to the same list, they are not individual per key
same_list = {'Bill': inputs, 'Sal': inputs, 'Pam': inputs}
different_list = {'Bill': [0, 0, 0, 0, 0, 0], 'Sal': [0, 0, 0, 0, 0, 0], 'Pam': [0, 0, 0, 0, 0, 0]}
 
def rating_update(key, index, rate):
    if key in same_list:
        same_list[key][index] = rate
        different_list[key][index] = rate

        
rating_update('Bill', 2, 3)
same_list
#{'Bill': [0, 0, 3, 0, 0, 0], 'Sal': [0, 0, 3, 0, 0, 0], 'Pam': [0, 0, 3, 0, 0, 0]}
inputs
#[0, 0, 3, 0, 0, 0]
different_list
#{'Bill': [0, 0, 3, 0, 0, 0], 'Sal': [0, 0, 0, 0, 0, 0], 'Pam': [0, 0, 0, 0, 0, 0]}
  • Related