从字典列表中提取多个键的值

Sak*_*are 1 python optimization dictionary list time-complexity

我是 Python 新手,正在寻求一些帮助。我的字典列表如下:

data = [
    {'device_id': 'D11', 'ipv4': '1.1.1.1'},
    {'device_id': 'D42', 'ipv4': '1.1.1.2'},
    {'device_id': 'D32', 'hostname': 'MVPQ021'},
    {'device_id': 'D94', 'ipv6': '2001:0db8:0:7334'}
]
Run Code Online (Sandbox Code Playgroud)

我只需要获取 IP 地址列表,如下所示:

['1.1.1.1', '1.1.1.2', '2001:0db8:0:7334']
Run Code Online (Sandbox Code Playgroud)

我尝试了以下方法,得到了我想要的结果:

result = []

    for x in data:
        if 'ipv4' in x.keys():
            result.append(x['ipv4'])
            continue
        if 'ipv6' in x.keys():
            result.append(x['ipv6'])
Run Code Online (Sandbox Code Playgroud)

然而,对于一个很长的列表,例如包含 1000 多个元素的列表,此解决方案效率不高。

是否有任何优化方法可以仅过滤掉ipv4ipv6值,而不迭代列表中的每个元素?

lmi*_*asf 5

假设您使用的是 Python 3.8+,您可以如下利用:=(walrus 运算符),并且可以在一个列表理解中完成该操作:

data = [
    {'device_id': 'D11', 'ipv4': '1.1.1.1'},
    {'device_id': 'D42', 'ipv4': '1.1.1.2'},
    {'device_id': 'D32', 'hostname': 'MVPQ021'},
    {'device_id': 'D94', 'ipv6': '2001:0db8:0:7334'}
]
result = [
    ip_address for e in data
    if (ip_address := e.get('ipv4') or e.get('ipv6')) is not None
]
Run Code Online (Sandbox Code Playgroud)

解释:

  1. 对于列表中的每个字典,您尝试获取键'ipv4'或的值'ipv6'并将其存储在ip_address.
  2. 如果两者都没有值,它将跳过该元素。