объединение словарей (с тем же ключом), которые содержат список в Python 3.7 - PullRequest
0 голосов
/ 27 января 2019

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

{'cartoon':['tom','jerry'],'film':['rose','jack','marry'],'serial':'little boy'}

Я использую Python 3.7.Можно ли запустить код без использования defaultdict?Я также пытался написать оператор печати, например:

print("{'cartoon':"+list(d1(key(value))+list(d2[key]+",'film':"+list(d1(key(value))+list(d2[key]+",'serial':"+list(d1(key(value))+list(d2(key(value))+"}"

, но он не работал, поэтому я написал следующий код:

from collections import defaultdict
d1 = {'cartoon': 'tom', 'film': 'rose'}
d2 = {'cartoon': 'jerry', 'film':['jack','marry'], 'serial' : 'little boy'}
new = defaultdict (list)
for char in (d1,d2):
    for key, value in char.iteritems():
        new[key].append(value)
print (new)

Я получаю сообщение об ошибке «AttributError»: объект 'dict' не имеет атрибута 'iteritems'.

Кто-нибудь может подсказать, как я могу это отредактировать? Заранее спасибо.

Ответы [ 3 ]

0 голосов
/ 27 января 2019

по списку вы можете сделать:

d1 = {'cartoon': 'tom', 'film': 'rose'}
d2 = {'cartoon': 'jerry', 'film':['jack','marry'], 'serial' : 'little boy'}
#normalizing dictionaries
d1={k: v if isinstance(v , list) else [v] for k,v in d1.items()}
d2={k: v if isinstance(v , list) else [v] for k,v in d2.items()}

d3={k:list(set().union(d1.get(k, []),d2.get(k, [])))  for k in  (d1.keys()|d2.keys())}

print(d3)

вывод:

{'cartoon': ['jerry', 'tom'], 'film': ['marry', 'rose', 'jack'], 'serial': ['little boy']}  

Если вы хотите показать отдельные значения в виде строки, вы можете сделать в конце:

d3={k:v if len(v)!=1 else v[0] for k,v in d3.items()}

вывод:

{'film': ['rose', 'marry', 'jack'], 'serial': 'little boy', 'cartoon': ['tom', 'jerry']}

Может быть, это то, что вы хотите сказать "все в одну строку":

d1 = {'cartoon': 'tom', 'film': 'rose'}
d2 = {'cartoon': 'jerry', 'film':['jack','marry'], 'serial' : 'little boy'}
#normalizing dictionaries
d1={k: v if isinstance(v , list) else [v] for k,v in d1.items()}
d2={k: v if isinstance(v , list) else [v] for k,v in d2.items()}

d3={k:list(set().union(d1.get(k, []),d2.get(k, []))) if len(set().union(d1.get(k, []),d2.get(k, [])))!=1 else list(set().union(d1.get(k, []),d2.get(k, [])))[0]   for k in  (d1.keys()|d2.keys())}

print(d3)
0 голосов
/ 27 января 2019

Попытка записать свою логику в одну строку вряд ли принесет какую-либо выгоду. Также обратите внимание, что dict.iteritems устарела в Python3 в пользу dict.items, что возвращает представление .

Вы можете переписать свою логику более четко, используя list.extend и троичное выражение. Поначалу функциональное решение выглядит запутанным, но допускает произвольное количество входных словарей, то есть (d1, d2, d3, ...), без обращения к явному вложенному циклу.

from collections import defaultdict
from itertools import chain
from operator import methodcaller

new = defaultdict(list)
for key, value in chain.from_iterable(map(methodcaller('items'), (d1, d2))):
    new[key].extend([value] if not isinstance(value, list) else value)

# defaultdict(list,
#             {'cartoon': ['tom', 'jerry'],
#              'film': ['rose', 'jack', 'marry'],
#              'serial': ['little boy']})
0 голосов
/ 27 января 2019

Если вы запустили этот Python 2, он бы работал, но поскольку он выглядит так, как будто вы находитесь на Python 3, этого не происходит, и вам придется заменить эту строку:

    for key, value in char.iteritems():

С:

    for key, value in char.items():

Или ниже, поскольку полный код будет намного короче:

print({k:(v+[d1[k]] if k in d1 else v) for k,v in d2.items()})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...