【问题标题】:combine a list of dictionaries with one key value match将字典列表与一个键值匹配组合
【发布时间】:2021-06-24 20:22:26
【问题描述】:
listofdicts = [
{
    "if-e0": "e0",
    "ip-add-e0": "192.168.1.1",
    "name": "host1"
},
{
    "if-e1": "e1",
    "ip-add-e1": "192.168.2.1",
    "name": "host1"
},
{
    "if-e1": "e1",
    "ip-add-e1": "172.16.1.1",
    "name": "host2"
},
{
    "if-e2": "e2",
    "ip-add-e2": "172.16.2.1",
    "name": "host2"
}]

预期结果:

listofdicts = [
{
    "if-e0": "e0",
    "ip-add-e0": "192.168.1.1",
    "if-e1": "e1",
    "ip-add-e1": "192.168.2.1",
    "name": "host1"
},
{
    "if-e1": "e1",
    "ip-add-e1": "172.16.1.1",
    "if-e2": "e2",
    "ip-add-e2": "172.16.2.1",
    "name": "host2"
}]

一直在尝试完成这项工作,但还没有成功,实际列表中有超过 60K 的字典,其中包含唯一且匹配的主机。

这可能更容易解决,但对我来说,这是过去几个小时的噩梦。

感谢您的帮助。

问候, 阿维纳什

【问题讨论】:

  • 嗨阿维纳什!请通过stackoverflow.com/help/formatting 使您的问题格式更清晰。它可以帮助其他人更好地理解您的代码和您的问题,他们将能够更快地为您提供帮助。
  • 好的,已经修复了格式,还是不行?谢谢

标签: python-3.x list-comprehension dictionary-comprehension


【解决方案1】:

@Kolay.Ne 嗨,大家好, 它确实适用于非常基本的捕获。 Graph 方法可以很好地解决它,尽管我使用了以下可行的方法:

for d in listofdicts:
    x = listofdicts.index(d)
    for y in range(len(listofdicts)):
        k = 'name'
        if y != x and y < len(listofdicts):
            if listofdicts[x][k] == listofdicts[y][k]:
                dc = copy.deepcopy(listofdicts[y])
                listofdicts[x].update(dc)
                listofdicts.remove(dc)

可能是其他方法来解决它,我确定可悲的方式只是几行,这解决了我手头工作的问题。

感谢 kolay.Ne 快速响应并尝试提供帮助,图形方法也很棒,需要专业的编码,并且肯定会更具可扩展性。

【讨论】:

    【解决方案2】:

    图论在这里似乎很有帮助。

    要解决这个问题,您需要构建一个图,其中每个顶点都与输入列表中的一个字典相关。

    如果对应的字典中有一个共同的键值对,则两个顶点之间应该有一条边(更具体地说,对于字典d1d2,如果len(set(d1.items()).intersection(d2.items())) != 0 或者更简单,则应该有一条边, ifset(d1.items()).intersection(d2.items())。条件表示d1d2的项集的交集中至少有一个键值对。

    图建好后,你需要找到所有的连接组件(这是一个非常简单的 DFS(深度优先搜索),如果你不熟悉图算法,你可以谷歌它)。每个连接组件的字典应该合并为一个:每个组件应该有一个结果字典。这些结果字典的列表就是您的答案。

    以下是如何组合一些字典的示例:

    connectivity_component_dicts = [{...}, ...]
    resulting_dict = {**d for d in connectivity_component_dicts}
    # Note that the greater the index of `d` in `connectivity_component_dicts`,
    # the higher priority its keys have if there are same keys in some dicts.
    

    【讨论】:

    • 非常感谢,准备试试。
    • @AvinashRai,祝你好运。如果您遇到困难或意识到您不理解我的解释中的某些内容,请随时寻求帮助
    • 嗨@kolay.Ne,是的,它确实有效。尽管我尝试了不同的方法,但这是解决问题的好方法
    【解决方案3】:
    a = []
    
    for i in listofdicts:
        if i["name"] not in a:
            a.append(i["name"])
            print(i)
    

    【讨论】:

    • 似乎既不能总能解决问题(声明中没有关于name 键的内容),也不能产生预期的结果
    • 非常感谢您的快速回复,但它覆盖了一个实例 host1 的接口,在新列表 a 中缺少其 e1,产生以下内容:{'if-e0': 'e0 ', 'ip-add-e0': '192.168.1.1', 'name': 'host1'} , 和 host2 缺少 e2。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-10
    • 1970-01-01
    • 2021-07-26
    • 2019-02-24
    • 1970-01-01
    相关资源
    最近更新 更多