【问题标题】:Effecient Way To Find If a Key From A List Of Dicts Exists In Within Another List Of Dicts In Python查找字典列表中的键是否存在于Python中的另一个字典列表中的有效方法
【发布时间】:2021-01-18 23:14:21
【问题描述】:

正如标题所说,我有两个字典列表。我们将它们称为 A,它存在于数据库中,而 B,它是来自传感器的实时结果。

A 与 B 共享键/值

示例如下:

A = [
    {
        "created_at": "2020-09-19T17:25:29.547354",
        "id": 1,
        "ip_address": "192.168.1.1",
        "mac_address": "xx:xx:xx:xx:xx:xx",
    },
    {
        "created_at": "2020-09-19T17:25:29.564472",
        "id": 2,
        "ip_address": "192.168.1.2",
        "mac_address": "xx:xx:xx:xx:xx:xx",
    },
    {
        "created_at": "2020-09-19T17:25:29.564472",
        "id": 3,
        "ip_address": "192.168.1.3",
        "mac_address": "xx:xx:xx:xx:xx:xx",
    }
]

B = [
    {
        'mac_address': 'xx:xx:xx:xx:xx:xx',
        'ip_address': '192.168.1.1',
        'status': True
    },
    {
        'mac_address': 'xx:xx:xx:xx:xx:xx',
        'ip_address': '192.168.1.2',
        'status': True
    }
]

根据值ip_address,找出 B 和 A 中缺失字典的最佳方法是什么。

例如,我们可以通过查看上面的内容来判断,包含 ip_address “192.168.1.3” 的字典在 B 中不存在。目的是尝试找到不存在于 B 之间的值列表两个,如果有的话。

感谢任何帮助!

编辑:

预期的输出是一个类似的列表:["192.168.1.3"]

【问题讨论】:

  • 需要匹配什么?只是IP地址还是mac地址?你想要的输出是什么? IP 地址,在A 中找到的字典,还有什么?
  • 好主意,我会更新帖子以显示预期输出
  • Syn,我认为 CHRIS 方法的有效方法是制作两组并找到差异。看看我对你代码的 1000000 次迭代的回答

标签: python arrays list dictionary multidimensional-array


【解决方案1】:

使用python的map函数获取结果的另一种方法

def get_ip_address(dict):
    return dict['ip_address']


missing_ips =[ ip for ip  in  map(get_ip_address,A) if ip  not in map(get_ip_address,B)]
print(missing_ips)

方法与 100000000 次迭代比较

CHRIS 方法获胜

import time
A = [
    {
        "created_at": "2020-09-19T17:25:29.547354",
        "id": 1,
        "ip_address": "192.168.1.1",
        "mac_address": "xx:xx:xx:xx:xx:xx",
    },
    {
        "created_at": "2020-09-19T17:25:29.564472",
        "id": 2,
        "ip_address": "192.168.1.2",
        "mac_address": "xx:xx:xx:xx:xx:xx",
    },
    {
        "created_at": "2020-09-19T17:25:29.564472",
        "id": 3,
        "ip_address": "192.168.1.3",
        "mac_address": "xx:xx:xx:xx:xx:xx",
    }
]

B = [
    {
        'mac_address': 'xx:xx:xx:xx:xx:xx',
        'ip_address': '192.168.1.1',
        'status': True
    },
    {
        'mac_address': 'xx:xx:xx:xx:xx:xx',
        'ip_address': '192.168.1.2',
        'status': True
    }
]

start_time = time.time()



st = time.time()
for i in range(100000000):
    if_addresses_A = {d['ip_address'] for d in A}
    list(if_addresses_A.difference(d['ip_address'] for d in B))

print("--- %s Andresh method takes seconds ---" % (time.time() - st))



st = time.time()
for i in range(100000000):
    set(x["ip_address"] for x in B).difference(set(x["ip_address"] for x in A))

print("--- %s Diago method takes seconds ---" % (time.time() - st))



st = time.time()
for i in range(100000000):
    [item1["ip_address"] for item1 in A if item1["ip_address"] not in [item2["ip_address"] for item2 in B]]


print("--- %s Yossi method takes seconds ---" % (time.time() - st))



st = time.time()
for i in range(100000000):
    ips_a = set([k['ip_address'] for k in A])
    ips_b = set([k['ip_address'] for k in B])
    ips_a - ips_b  # {'192.168.1.3'}

print("--- %s CHRIS method takes seconds ---" % (time.time() - st))


st = time.time()
for i in range(100000000):
    def get_ip_address(dict):
        return dict['ip_address']


    [ ip for ip  in  map(get_ip_address,A) if ip  not in map(get_ip_address,B)]

print("--- %s My method takes seconds ---" % (time.time() - st))

代码输出

【讨论】:

    【解决方案2】:

    另一种选择是使用嵌套列表推导:

    missing_ips = [item1["ip_address"] for item1 in A if item1["ip_address"] not in [item2["ip_address"] for item2 in B]]
    print(missing_ips)
    
    #['192.168.1.3']
    

    【讨论】:

      【解决方案3】:
      set(x["ip_address"] for x in B).difference(set(x["ip_address"] for x in A))
      

      顺便说一句,在您的示例中,来自 B 的所有 ip_addresses 也在 A 中,因此产生的差异是空的(但这是一个数据问题 :-)

      【讨论】:

        【解决方案4】:

        您可以比较每个ips的set

        ips_a = set([k['ip_address'] for k in A])
        ips_b = set([k['ip_address'] for k in B])
        missing = ips_a - ips_b  # {'192.168.1.3'}
        

        【讨论】:

        • 我赞成它,因为它比其他方法更有效,但是如果我们在 B 中而不是在 A 中,那么该值也将丢失
        【解决方案5】:

        你可以使用set.difference:

        if_addresses_A = {d['ip_address'] for d in A}
        print(if_addresses_A.difference(d['ip_address'] for d in B))
        

        打印:

        {'192.168.1.3'}
        

        或以列表形式:

        if_addresses_A = {d['ip_address'] for d in A}
        print(list(if_addresses_A.difference(d['ip_address'] for d in B)))
        

        打印:

        ['192.168.1.3']
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2022-01-10
          • 2021-05-31
          • 2022-06-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多