简体   繁体   中英

How to update a large dictionary using a list quickly?

I am looking for a fast way to update the values in a (ordered) dictionary, which contains tens of millions of values, where the updated values are stored in a list/array.

The program I am writing takes the list of keys from the original dictionary (which are numerical tuples) as a numpy array, and passes them through a function which returns an array of new numbers (one for each key value). This array is then multiplied with the corresponding dictionary values (through piece-wise array multiplication), and it is this returned 1-D array of values that we wish to use to update the dictionary. The entries in the new array are stored in the order of the corresponding keys, so I could use a loop to go through the dictionary a update the values one-by-one. But this is too inefficient. Is there a faster way in which to update the values in this dictionary which doesn't use loops?

An example of a similar problem would be if the keys in a dictionary represent the x and y-coordinates of points in space, and the values represent the forces being applied at that point. If we want to calculate the torque experienced at each point from the origin, we would first need a function like:

def euclid(xy):
   return (xy[0]**2 + xy[1]**2)**0.5

Which, if xy represents the x, y-tuple, would return the Euclidean distance from the origin. We could then multiply this by the corresponding dictionary value to return the torque, like so:

for xy in dict.keys():
   dict[xy] = euclid(xy)*dict[xy]

But this loop is slow, and we could take advantage of array algebra to get the new values in one operation:

new_dict_values = euclid(np.array(dict.keys()))*np.array(dict.values())

And it is here that we wish to find a fast method to update the dictionary, instead of utilising:

i = 0
for key in dict.keys():
    dict[key] = new_dict_value[i]
    i += 1

That last piece of code isn't just slow. I don't think it does what you want it to do:

for key in dict.keys():
    for i in range(len(new_dict_values)):
        dict[key] = new_dict_value[i]

For every key in the dictionary, you are iterating through the entire list of new_dict_values and assigning each one to the value of that key, overwriting the value you assigned in the previous iteration of the loop. This will give you a dictionary where every key has the value of the last element in new_dict_value, which I don't think is what you want.

If you are certain that the order of the keys in the dictionary is the same as the order of the values in new_dict_values, then you can do this:

for key, value in zip(dict.keys(), new_dict_values):
    dict[key] = value

Edit: Also, in the future there is no need in python to iterate through a range of numbers and access elements of a list via the index. This:

for i in range(len(new_dict_values)):
        dict[key] = new_dict_value[i]

is equivalent to this:

for i in new_dict_values:
        dict[key] = i

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM