У меня есть следующие словари dic1 = {'T1': «Привет, Китай», 'T2': «Привет, Финляндия», 'T3': «Привет, Германия»} dic2 = {'T1': ['INC1', 'INC2', 'INC3'], 'T2': ['INC2', 'INC4', '...

2
Fusdev 16 Янв 2021 в 21:20

3 ответа

Лучший ответ

Можно сделать однострочным:

>>> {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, если dic3[i]['location'] находится внутри dic1[k], где i - ключ в dict d3 и k - это ключ от dict d2, а также от dict d1.

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

Я возвращаю # (может быть любой строкой / символом), если знаю, что ключ i не существует в dic3 (i не существует, по существу даст {{X4 }} что, в свою очередь, даст #, это обязательно приведет к отказу от членства в 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']}
3
Jarvis 16 Янв 2021 в 19:01

Насколько я понимаю, вы должны изменить исходный словарь 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. Следующий проходит по спискам (значениям) и добавляет их в список удаления. В конце каждого цикла он выполняет итерацию по списку удаления, удаляя каждый элемент из списка значений, а затем устанавливает для удаления пустой список.

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

1
thomaoc 16 Янв 2021 в 19:16

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

{k: [el] for k, v in dic2.items() for el in v if (el in dic3.keys() and dic3[el]['location'] in dic1[k])}
0
NewbieAF 16 Янв 2021 в 20:01
65753082