首页 > 解决方案 > 如何将嵌套字典与另一个嵌套字典组合,但仅当每个嵌套字典都有匹配值时?

问题描述

我可以描述我想要实现的最佳方式是参考 SQL 函数如何INNER JOIN工作以显示两个表中的数据,由匹配的列名确定。

我想实现一个类似的功能,但通过使用 Python(最好是 3.x),而不是具有匹配列名的表,我想根据匹配的 {k 将两个字典的全部组合在一起: v} 对。

例如...

lst_1 = [
    {
        'City'      :   'Boston',
        'State'     :   'Massechusets',
        'Name'      :   'Kim Tuttles',
        'Country'   :   'United State'
    },
    {
        'City'      :   'Portland',
        'Name'      :   'Larry Bird',
        'State'     :   'Oregon'
    },
    {
        'City'      :   'Chicago',
        'Name'      :   'John Jacobs',
        'State'     :   'Illinois'
    }
]

lst_2 = [
    {
        'Hobby'     :   'Tennis',
        'Build'     :   'Athletic',
        'Height'    :   'Six Feet, One Inch',
        'Name'      :   'Kim Tuttles',
        'Birthplace':   'Italy'
    },
    {
        'Name'      :   'John Jacobs',
        'Hobby'     :   'Baseball',
        'Build'     :   'Muscular',
        'Height'    :   'Five Feet, Eight Inches'
    }
]

我想找到一种方法来合并每个列表中的字典,但仅限于找到匹配的 {Key: Value} 对的地方。结果看起来像这样......

merged_lst = [
    {
        'Hobby'     :   'Tennis',
        'Build'     :   'Athletic',
        'Height'    :   'Six Feet, One Inch',
        'Birthplace':   'Italy'
        'City'      :   'Boston',
        'State'     :   'Massechusets',
        'Name'      :   'Kim Tuttles', # Merge on matching name
        'Country'   :   'United State'
    },
    {
        'Name'      :   'John Jacobs', # Merge on matching name
        'Hobby'     :   'Baseball',
        'Build'     :   'Muscular',
        'Height'    :   'Five Feet, Eight Inches'
        'City'      :   'Chicago',
        'State'     :   'Illinois'
    }
]

我设法找到了一种使用dict.updateand合并字典的方法zip(),尽管那只是在处理两个独立的字典时,它仍然不太正确。感谢您的任何建议,并在此先感谢您。

标签: pythonjsonpython-3.xdictionarynested

解决方案


在 Python 3.5+ 中,我们可以摆脱以下问题,而忽略其他键冲突的问题。

k = 'Name'
merged_lst = [{**a, **b} for a in lst_1 for b in lst_2 if a[k]==b[k]]
  • {**a, **b}是将正在考虑的两个字典解包到组合字典中的一种巧妙方法(我相信在冲突中它使用值 fromb而不是a)。这是唯一需要 3.5+ 的步骤。在带有字符串键的Python 2.x 中,类似的结构是dict(a, **b),尽管 Guido 对此深表不满。其他选项更详细。
  • Python 列表推导式允许您通过使用两次来lst_1轻松迭代有效的笛卡尔积。lst_2for
  • 我们只关心具有相同的字典'Name',因此是a[k]==b[k]位。
  • 如果允许您破坏lst_1or中的任何字典,则lst_2涉及dict.update()的方法可能更快。无论如何,它们可能是这样,尽管我认为语法没有那么好。

推荐阅读