Python 合并到保留不同值的词典

Python 合并到保留不同值的词典,python,dictionary,merge,Python,Dictionary,Merge,我对python(Python3.2)非常陌生,我一直在努力解决一个难题。我有两本列出清单的词典: d1 = { 'mammals': ['dog', '5', 'cat', '4', 'mouse', '4', 'bat', '3'], 'bird': ['robin', '8', 'bluejay', '6', 'goose', '5', 'cardinal', '5'] } 及 在每个字典中,配对名称编号(例如,'dog',5')对应于原始数据库中所述项目的实例数量 我需要的是以一种方

我对python(Python3.2)非常陌生,我一直在努力解决一个难题。我有两本列出清单的词典:

d1 = {
'mammals': ['dog', '5', 'cat', '4', 'mouse', '4', 'bat', '3'], 
'bird': ['robin', '8', 'bluejay', '6', 'goose', '5', 'cardinal', '5']
}

在每个字典中,配对名称编号(例如,
'dog',5'
)对应于原始数据库中所述项目的实例数量

我需要的是以一种方式合并这两个词典,以确保有关保留数量的信息(同样,在本例中,新词典将具有
'dog','5','3'
),以便合并后的词典看起来有点像(我不一定要使用嵌套字典。我这样写是为了便于可视化。重要的是太多地保留信息):


我尝试过使用元组、嵌套字典和其他可能的方法,但结果是一团糟。如果有人能给我指出解决这个问题的好方法,这将意味着很多。我非常感谢您首先您可以将d1和d2更改为更易于使用的字典:

[请注意,列表[::2]是包含偶数索引中所有项目的子列表,而列表[1::2]包含赔率。]

>>> dc1 = {}
>>> for family in d1.keys():
        l = d1[family]
        dc1[family] = {l[::2][family]:[l[1::2][family]] for family in range(len(l)/2)}


>>> dc2 = {}
>>> for family in d1.keys():
        l = d2[family]
        dc2[family] = {l[::2][family]:[l[1::2][family]] for family in range(len(l)/2)}
现在dc1和dc2是:

>>> dc1
{'mammals': {'bat': ['3'], 'mouse': ['4'], 'dog': ['5'], 'cat': ['4']},
 'bird': {'goose': ['5'], 'cardinal': ['5'], 'robin': ['8'], 'bluejay': ['6']}}
>>> dc2
{'mammals': {'beaver': ['3'], 'horse': ['4'], 'dog': ['3'], 'cow': ['5'], 'cat': ['4']}, 
'bird': {'eagle': ['8'], 'bluejay': ['9'], 'goose': ['8'], 'cardinal': ['5'], 'duck': ['6'], 'robin': ['7']}}
然后你只需要把它们结合起来

>>> d_merged = {}
>>> families = set(d1.keys()+d2.keys())
>>> family2animals = {family:list(set(dc1[family].keys()+dc2[family].keys())) for family in families}
>>> for family in families:
        d_merged[family] = [{animal:dc1[family].get(animal,[])+dc2[family].get(animal,[])} for animal in family2animals[family]]

首先,您可以将d1和d2更改为更易于使用的词典:

[请注意,列表[::2]是包含偶数索引中所有项目的子列表,而列表[1::2]包含赔率。]

>>> dc1 = {}
>>> for family in d1.keys():
        l = d1[family]
        dc1[family] = {l[::2][family]:[l[1::2][family]] for family in range(len(l)/2)}


>>> dc2 = {}
>>> for family in d1.keys():
        l = d2[family]
        dc2[family] = {l[::2][family]:[l[1::2][family]] for family in range(len(l)/2)}
现在dc1和dc2是:

>>> dc1
{'mammals': {'bat': ['3'], 'mouse': ['4'], 'dog': ['5'], 'cat': ['4']},
 'bird': {'goose': ['5'], 'cardinal': ['5'], 'robin': ['8'], 'bluejay': ['6']}}
>>> dc2
{'mammals': {'beaver': ['3'], 'horse': ['4'], 'dog': ['3'], 'cow': ['5'], 'cat': ['4']}, 
'bird': {'eagle': ['8'], 'bluejay': ['9'], 'goose': ['8'], 'cardinal': ['5'], 'duck': ['6'], 'robin': ['7']}}
然后你只需要把它们结合起来

>>> d_merged = {}
>>> families = set(d1.keys()+d2.keys())
>>> family2animals = {family:list(set(dc1[family].keys()+dc2[family].keys())) for family in families}
>>> for family in families:
        d_merged[family] = [{animal:dc1[family].get(animal,[])+dc2[family].get(animal,[])} for animal in family2animals[family]]

最具可读性的方法可能如下所示:

output = {}
for key in d1.keys():
    output[key] = {}
    lst = d1[key]
    for name, count in (lst[i:i+2] for i in range(0, len(lst), 2)):
        output[key][name] = (int(count),)
for key in d2.keys():
    if key not in output:
        output[key] = {}
    lst = d2[key]
    for name, count in (lst[i:i+2] for i in range(0, len(lst), 2)):
        if name in output[key].keys():
            output[key][name] += (int(count),)
        else:
            output[key][name] = (int(count),) 
在难以理解的词典理解中,你可以分两步完成

d = {k: {a: int(b) for a, b in (v[i:i+2] for i in range(0, len(v), 2))} 
     for k, v in d.items()}
把它们变成字典中的字典,例如

{'mammals': {'cat': 4, 'cow': 5, 'dog': 3, 'beaver': 3, 'horse': 4}, 
 'bird': {'goose': 8, 'duck': 6, 'eagle': 8, 'bluejay': 9, 'robin': 7, 'cardinal': 5}}
然后

把两者结合起来


请注意,即使在两个级别上有不同的键(例如,添加
d1['爬行动物]={'lizard':10}
),这些方法也可以工作。

最可读的方法可能如下所示:

output = {}
for key in d1.keys():
    output[key] = {}
    lst = d1[key]
    for name, count in (lst[i:i+2] for i in range(0, len(lst), 2)):
        output[key][name] = (int(count),)
for key in d2.keys():
    if key not in output:
        output[key] = {}
    lst = d2[key]
    for name, count in (lst[i:i+2] for i in range(0, len(lst), 2)):
        if name in output[key].keys():
            output[key][name] += (int(count),)
        else:
            output[key][name] = (int(count),) 
在难以理解的词典理解中,你可以分两步完成

d = {k: {a: int(b) for a, b in (v[i:i+2] for i in range(0, len(v), 2))} 
     for k, v in d.items()}
把它们变成字典中的字典,例如

{'mammals': {'cat': 4, 'cow': 5, 'dog': 3, 'beaver': 3, 'horse': 4}, 
 'bird': {'goose': 8, 'duck': 6, 'eagle': 8, 'bluejay': 9, 'robin': 7, 'cardinal': 5}}
然后

把两者结合起来


请注意,即使在两个级别上有不同的键(例如,添加
d1['爬行动物]={'lizard':10}
),这些方法也可以工作。

您可以更改起始数据结构吗?如果有一个(名称、计数)列表会更有意义元组,而不是交替名称和计数的列表。@jonrsharpe原始数据结构具有这种格式。在合并之前,我试图以各种方式对其进行更改,但均未成功。向我们展示您尝试过的失败代码。您能更改起始数据结构吗?使用(名称、计数)列表更有意义元组,而不是交替名称和计数的列表。@jonrsharpe原始数据结构有这种格式。在合并之前,我试图以各种方式对其进行更改,但均未成功。请向我们展示您尝试过的失败代码。非常感谢您,我真的很想了解您应用的第二种方法,但我得到了error:
AttributeError:“list”对象没有属性“keys”
。你知道这是怎么发生的吗?如果你不在每个源字典上运行预处理步骤(
d={k:{a:int(b)…
),就会出现这个错误;否则,
d1.get(k1,{})如果
k1
d1
中的一个键,则
将返回一个列表,并列出(如错误消息所示)没有密钥。再次感谢你。你是对的,我没有在最后一行正确替换名称,这就是我出错的原因。尽管如此,此解决方案并不能满足我的需要,因为它汇总了初始字典上的信息(例如,
“dog”:“8”
)实际上,我需要保存两条信息<代码>'dog':['5','3']
。如果只在一本词典中怎么办?你想让另一本词典中有一个零吗?还是列表中只有一项?我真的很感谢你的帮助和时间。理想的情况是只有一个值,但是零也可以!非常感谢你,我真的很想了解你应用的第二种方法,但我得到了错误:
tributeError:'list'对象没有属性'keys'
。你知道这是怎么发生的吗?如果你不在每个源字典上运行预处理步骤(
d={k:{a:int(b)…
),就会出现这个错误;否则,
d1.get(k1,{})
将返回一个列表,如果
k1
d1
中的一个键,则返回列表(正如错误消息所说)没有密钥。再次感谢。你是对的,我没有在最后一行正确替换名称,这就是我出错的原因。尽管如此,此解决方案并不能满足我的需要,因为它汇总了初始字典上的信息(例如,
'dog':'8'
)事实上,我需要保留两条信息
'dog':['5','3']
。如果它只在一本字典中呢?你希望另一本字典为零吗?还是列表中只有一项?我非常感谢你的帮助和你的时间。理想情况是只有一个值,但零也可以!