Перебирать список словарей и сравнивать с другими словарями

#python #python-3.x #list #dictionary

#python #python-3.x #Список #словарь

Вопрос:

У меня есть следующие словари

 dic1 = { 'T1': "HI , china" , 'T2': "HI , finland" ,'T3': "HI , germany"}

dic2 = { 'T1': ['INC1','INC2','INC3'] , 'T2': ['INC2','INC4','INC5'],'T3': ['INC2','INC5']}

dic3 = { 'INC1': {'location':'china'} , 'INC2': {'location':'germany'},'INC3': {'location':'germany'},'INC4': {'location':'finland'}} 
 

Мне нужно удалить значения в dic2 на основе dic1, dic3

пример :

  1. Сначала я должен выполнить итерацию через dic2 и проверить значения T1 и его INC.
  2. Если соответствующее значение ключа T1 в Dic1 совпадает с соответствующими значениями INC в dic3, сохраните значение в dic2, в противном случае введите значение.

Подробное объяснение приведено на картинке. И я ожидаю следующего вывода.

 dic2 = { 'T1': ['INC1'] , 'T2': ['INC4'],'T3': ['INC2']}
 

введите описание изображения здесь

пример кода :

 for k, v in dic2.items():
for k1, v1 in dic1.items():
    if k is k1:
        print k
        for k2 in v:
            for k3 in dic3.items():
  
 

Я новичок в python. Я попробовал вышеупомянутые фрагменты кода, и я был поражен.Не могли бы вы мне помочь.

Ответ №1:

Может быть выполнено в однострочном:

 >>> {k: [i for i in v if dic3.get(i, {}).get('location', '#') in dic1[k]] for k, v in dic2.items()}
{'T1': ['INC1'], 'T2': ['INC4'], 'T3': ['INC2']}
 

[i for i in v if dic3.get(i, {}).get('location', '#') является ли понимание списка для выбора только значений из dic2 списков if dic3[i]['location'] внутри dic1[k] , где i является ключом в dict d3 и k является ключом из dict d2 , а также dict d1 .

Я использовал dic3.get(i, {}).get('location', '#') (вместо dic3[i]['location'] , вы получаете KeyError для ключа, INC5 которого нет dic3 ), чтобы избежать проблемы отсутствия ключа i dic3 (вернет пустое значение dict для моего следующего .get ), а во втором .get , снова я использую его, чтобы вернуть соответствующее location значение ключа, если оно существует, и проверить, лежит ли эта возвращаемая строка внутризначения dict d1 .

Я возвращаю # (может быть любой строкой / символом), если я знаю, что ключ i не существует в dic3 ( i не существующий, по сути, даст {}.get('location', '#') , что, в свою очередь, даст # , это обязательно приведет к сбою членства d1 , следовательно, все в порядке).

Уменьшенная версия для цикла:

 >>> ans = {}
>>> for k, v in dic2.items():
...     temp = []
...     for i in v:
...             if i in dic3 and dic3[i]['location'] in dic1[k]:
...                     temp.append(i)
...     ans[k] = temp
... 
>>> ans
{'T1': ['INC1'], 'T2': ['INC4'], 'T3': ['INC2']}
 

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

1. Точечный. однострочный — проблема. dense в этом случае слишком сложно читать. Возможно, другая версия for-loop для отображения и сравнения. Отличная работа.

Ответ №2:

Насколько я понимаю, вы должны изменить исходный словарь dic2, а не создавать новый для своего ответа, вот что я получил:

 delete = []

for key, value in dic2.items():
    loc = dic1[key][5:]
    for inc in value:
        if inc not in dic3:
            delete.append(inc)
        else:
            if loc != dic3.get(inc)['location']:
                delete.append(inc)

    for item in delete:
        value.remove(item)
    delete = []

print(dic2)

>>> {'T1': ['INC1'], 'T2': ['INC4'], 'T3': ['INC2']}
 

Первый цикл for выполняет итерацию через dic2 и устанавливает требуемое местоположение для переменной loc. Следующий перебирает списки (значения) и добавляет их в список удаления.
В конце каждого цикла он выполняет итерацию по списку удаления, удаляя каждый элемент из списка значений, а затем устанавливая delete в пустой список.

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

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

1. Это тоже сработало .. но я могу одобрить только один. Большое спасибо за ваш ответ

Ответ №3:

Это, по сути, то же самое, что и другие ответы, но как однострочный, он может быть более читаемым (возможно, нет, поскольку он субъективный).

 {k: [el] for k, v in dic2.items() for el in v if (el in dic3.keys() and dic3[el]['location'] in dic1[k])}