#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
пример :
- Сначала я должен выполнить итерацию через dic2 и проверить значения T1 и его INC.
- Если соответствующее значение ключа 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])}