Обновление словаря с помощью другого k / v в python

#python #dictionary

#python #словарь

Вопрос:

Мне неприятно спрашивать об этом, но я не могу в этом разобраться, и это меня достает.

Я должен создать функцию, которая принимает данный словарь d1 и вроде как сравнивает его с другим словарем, d2 затем добавляет сравниваемое значение в d2 .

d1 уже в формате, необходимом для того, чтобы мне не приходилось беспокоиться об этом. d2 однако это вложенный словарь. Это выглядит следующим образом:

 {’345’: {’Name’: ’xyzzy’, ’ID’: ’345’, ’Responses’: {’Q3’: ’c’, ’Q1’: ’a’, ’Q4’: ’b’, ’Q2’: ’a’}},
’123’: {’Name’: ’foo’, ’ID’: ’123’, ’Responses’: {’Q3’: ’c’, ’Q1’: ’a’, ’Q4’: ’a’, ’Q2’: ’b’}},
’234’: {’Name’: ’bar’, ’ID’: ’234’, ’Responses’: {’Q3’: ’c’, ’Q1’: ’a’, ’Q4’: ’b’, ’Q2’: ’b’}}}
  

So d1 находится в формате Responses ключа, и это то, что мне нужно от d2 , чтобы сравнить его с d1 .

Итак, чтобы сделать это, я изолирую responses :

     for key, i in d2.items():
    temp = i['Responses']
  

Теперь мне нужно запустить temp через функцию с d1 , которая выведет целое число. Затем сопоставьте это целое число с ключом верхнего уровня, из которого оно было получено, и обновите новую запись k / v, связанную с ним. Но я не знаю, как это сделать.

Мне удалось обновить каждый ключ верхнего уровня этим сравниваемым значением, но для всех ключей верхнего уровня используется только первое сравниваемое значение. Я не могу понять, как сопоставить найденное целое число с его ключом. Это то, что у меня пока что работает лучше всего:

     for  i in d2:
        score = grade_student(d1,temp)        #integer
        placement = {'Score': score}
        d2[i].update(placement)
  

Ответ №1:

Вы могли бы просто перебирать вложенные словари в d2 и обновлять их после вызова grade_student :

 for v in d2.values():
    v['Score'] = grade_student(d1, v['Responses'])
  

Вот полный пример:

 import pprint

d1 = {}
d2 = {
    '345': {'Name': 'xyzzy', 'ID': '345', 'Responses': {'Q3': 'c', 'Q1': 'a', 'Q4': 'b', 'Q2': 'a'}},
    '123': {'Name': 'foo', 'ID': '123', 'Responses': {'Q3': 'c', 'Q1': 'a', 'Q4': 'a', 'Q2': 'b'}},
    '234': {'Name': 'bar', 'ID': '234', 'Responses': {'Q3': 'c', 'Q1': 'a', 'Q4': 'b', 'Q2': 'b'}}
}

# Dummy
def grade_student(x, y):
    return 1

for v in d2.values():
    v['Score'] = grade_student(d1, v['Responses'])

pprint.pprint(d2)
  

Вывод:

 {'123': {'ID': '123',
         'Name': 'foo',
         'Responses': {'Q1': 'a', 'Q2': 'b', 'Q3': 'c', 'Q4': 'a'},
         'Score': 1},
 '234': {'ID': '234',
         'Name': 'bar',
         'Responses': {'Q1': 'a', 'Q2': 'b', 'Q3': 'c', 'Q4': 'b'},
         'Score': 1},
 '345': {'ID': '345',
         'Name': 'xyzzy',
         'Responses': {'Q1': 'a', 'Q2': 'a', 'Q3': 'c', 'Q4': 'b'},
         'Score': 1}}
  

Комментарии:

1. Я знаю, что я не должен использовать эти комментарии для благодарности, но, черт возьми, спасибо вам. Никогда бы не подумал сделать это.

Ответ №2:

Вам не нужно повторять их. Используйте встроенный update() метод. Вот пример

 >>> A = {'cat':10, 'dog':5, 'rat':50}
>>> B =  {'cat':5, 'dog':10, 'pig':20}
>>> A.update(B) #This will merge the dicts by keeping the values of B if collision
>>> A
{'rat': 50, 'pig': 20, 'dog': 10, 'cat': 5}
>>> B
{'pig': 20, 'dog': 10, 'cat': 5}
  

Комментарии:

1. Я действительно пробовал это, но это обновило только 1 из 3 ключей верхнего уровня. Вот почему я попытался выполнить итерацию.

2. На самом деле это не обновляет один из ключей, на самом деле это просто добавляет еще одну запись k / v отдельно от ключей.