简体   繁体   中英

Replace values of dictionaries (in a list) with a value in list of lists

below is my list of dictionaries I am working with (I have kept to 2 on purpose):

ld= [{'this': 1, 'is': 1, 'the': 1, 'first': 1, 'document': 1}, {'this': 1, 'document': 2, 'is': 1, 'the': 1, 'second': 1}]

Below is my list of lists (I have kept to 2 on purpose):

b=[[0.2, 0.2, 0.2, 0.2, 0.2], [0.16666666666666666, 0.3333333333333333, 0.16666666666666666, 0.16666666666666666, 0.16666666666666666]]

The count of dict keys is 10, and the count of values in b is also 10. I want to replace the values in b with dict.values() in list ld with same index value (ie "this" key in first dict should get the first value in b). How can I achieve this task?

Here is a quick, inelegant solution:

ld= [{'this': 1, 'is': 1, 'the': 1, 'first': 1, 'document': 1}, {'this': 1, 'document': 2, 'is': 1, 'the': 1, 'second': 1}]

b=[[0.2, 0.2, 0.2, 0.2, 0.2], [0.16666666666666666, 0.3333333333333333, 0.16666666666666666, 0.16666666666666666, 0.16666666666666666]]

for i, dictionary in enumerate(ld):
    for j, key in enumerate(dictionary):
        dictionary[key] = b[i][j]

print(ld)

We loop over the dictionary and index it such that we can reference the list b to pull corresponding values.

Using this as a starting point, we can now write a better code using list comprehension.

new_list = [{key: b[i][j]} for i, dictionary in enumerate(ld) for j, key in enumerate(dictionary)]

In both cases, we get the expected output:

>>> new_list
[{'this': 0.2}, {'is': 0.2}, {'document': 0.2}, {'the': 0.2}, {'first': 0.2}, {'this': 0.16666666666666666}, {'is': 0.3333333333333333}, {'document': 0.16666666666666666}, {'the': 0.16666666666666666}, {'second': 0.16666666666666666}]

I'd be happy to answer any additional questions you might have.

EDIT

@PacketLoss's rightly points out that the output of my code messes with the error. Therefore, we might consider an alternate implementation with collections.OrderedDict . Concretely,

from collections import OrderedDict

for i, dictionary in enumerate(ld):
    dictionary = OrderedDict(dictionary)
    for j, key in enumerate(dictionary):
        dictionary[key] = b[i][j]

This maintains the sequential integrity of the original dictionary.

With dictionaries the key order is not preserved ( Unless using Python 3.6+ ). This means when you try utilise the index of your list items to set values to the order of keys, your data can and will be set to the wrong keys.

Given you commented that you have a secondary list, containing key names. It would be best to use this to map the indexes of your data and keys together, then update your original dictionary with the values.

for indx, values in enumerate(b): # For index, and value in list
    data = list(zip(values, klist[indx])) # Zip the elements in your list with the list located at the same index in klist
    for row in data: # For tuple in [(0.2, 'this'), (0.2, 'is'), (0.2, 'the'), (0.2, 'first'), (0.2, 'document')]
        ld[indx][row[1]] = row[0]

All of the above will update the values in your original dictonary, insuring that the values in both your lists are mapped to the correct keys, not a random order.

#[{'this': 0.2, 'is': 0.2, 'the': 0.2, 'first': 0.2, 'document': 0.2}, {'this': 0.16666666666666666, 'document': 0.3333333333333333, 'is': 0.16666666666666666, 'the': 0.16666666666666666, 'second': 0.16666666666666666}]

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