合并字典(具有相同键),该字典包含python 3.7中的列表

时间:2019-01-26 23:59:02

标签: python list dictionary

我正在尝试用相同的键合并我的字典,但这有点不同,因为其中一个字典包含一个列表。我试图得到一个输出,如果合并的字典中有多个值,例如:

,它也会给我返回一个列表。
{'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 :(得分:0)

如果您已经运行了该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()})

答案 1 :(得分:0)

您可以通过列表理解:

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)

答案 2 :(得分:0)

尝试将您的逻辑写成一行不太可能带来任何好处。另请注意,在Python3中不推荐使用dict.iteritems,而推荐使用dict.items,它返回一个 view

您可以使用list.extend和三元语句来更清楚地重写逻辑。该功能性解决方案最初看起来很模糊,但它允许任意数量的输入字典,即(d1, d2, d3, ...),而无需使用 explicit 嵌套循环。

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']})