按项目过滤的新字典
New dict filtered by item
你能帮我解决这个简单的问题吗,不幸的是我不明白。
我有一个列表和另外两个带有字典列表的列表(但它可以是更多列表)。
a = [
[
{'DESCRIP': '', 'INTF': 'Vl77', 'PROTOCOL': 'up', 'STATUS': 'up'},
{'DESCRIP': '', 'INTF': 'Fa0', 'PROTOCOL': 'down', 'STATUS': 'admin down'}
],
[
{'INBOUND_ACL': '', 'INTF': 'Vlan77', 'IPADDR': ['192.168.77.11/24'], 'IP_HELPER': [], 'LINK_STATUS': 'up', 'MTU': '1500', 'OUTGOING_ACL': '', 'PROTOCOL_STATUS': 'up', 'VRF': ''},
{'INBOUND_ACL': '', 'INTF': 'FastEthernet0', 'IPADDR': [], 'IP_HELPER': [], 'LINK_STATUS': 'administratively down', 'MTU': '', 'OUTGOING_ACL': '', 'PROTOCOL_STATUS': 'down', 'VRF': ''}
]
]
我的目标是获得合并字典的最终列表,该列表由规则导出('合并所有包含 'INTF' 字段且编号相同的字典,在本例中为 77 或 0 ,换句话说按接口号过滤').
像那样
new_dict = [
{'DESCRIP': '', 'PROTOCOL': 'up', 'STATUS': 'up','INBOUND_ACL': '', 'INTF': 'Vlan77', 'IPADDR': ['192.168.77.11/24'], 'IP_HELPER': [], 'LINK_STATUS': 'up','MTU': '1500', 'OUTGOING_ACL': '', 'PROTOCOL_STATUS': 'up', 'VRF': ''},
{'DESCRIP': '', 'PROTOCOL': 'down', 'STATUS': 'admin down','INBOUND_ACL': '', 'INTF': 'FastEthernet0', 'IPADDR': [], 'IP_HELPER': [], 'LINK_STATUS': 'administratively down', 'MTU': '', 'OUTGOING_ACL': '', 'PROTOCOL_STATUS': 'down', 'VRF': ''}
]
由于我们希望根据键合并 dicts
,我认为最好的起点是重塑我们的数据以促进基于键的查找。在重塑数据的同时,我们还要创建一个仅包含数字的键。
import re
a_reshaped = [
{re.search(r'\d+', x["INTF"]): x for x in y}
for y in a
]
print(a_reshaped )
这会给我们:
[
{
'77': {'DESCRIP': '', 'INTF': 'Vl77', 'PROTOCOL': 'up', 'STATUS': 'up'},
'0': {'DESCRIP': '', 'INTF': 'Fa0', 'PROTOCOL': 'down', 'STATUS': 'admin down'}
},
{
'77': {'INBOUND_ACL': '', 'INTF': 'Vlan77', 'IPADDR': ['192.168.77.11/24'], 'IP_HELPER': [], 'LINK_STATUS': 'up', 'MTU': '1500', 'OUTGOING_ACL': '', 'PROTOCOL_STATUS': 'up', 'VRF': ''},
'0': {'INBOUND_ACL': '', 'INTF': 'FastEthernet0', 'IPADDR': [], 'IP_HELPER': [], 'LINK_STATUS': 'administratively down', 'MTU': '', 'OUTGOING_ACL': '', 'PROTOCOL_STATUS': 'down', 'VRF': ''}
}
]
此时我们可以迭代a_reshaped
并根据键合并字典。我们可以将此部分基于 setdefault()
或 collections.defaultdict()
。我自己更喜欢第二种。
import collections
results = collections.defaultdict(dict)
for c in a_reshaped:
for key, value in c.items():
results[key] = {**results[key], **value}
print(list(results.values()))
给我们:
[
{'DESCRIP': '', 'INTF': 'Vlan77', 'PROTOCOL': 'up', 'STATUS': 'up', 'INBOUND_ACL': '', 'IPADDR': ['192.168.77.11/24'], 'IP_HELPER': [], 'LINK_STATUS': 'up', 'MTU': '1500', 'OUTGOING_ACL': '', 'PROTOCOL_STATUS': 'up', 'VRF': ''},
{'DESCRIP': '', 'INTF': 'FastEthernet0', 'PROTOCOL': 'down', 'STATUS': 'admin down', 'INBOUND_ACL': '', 'IPADDR': [], 'IP_HELPER': [], 'LINK_STATUS': 'administratively down', 'MTU': '', 'OUTGOING_ACL': '', 'PROTOCOL_STATUS': 'down', 'VRF': ''}
]
基于collections.defaultdict()
的完整解决方案是:
import re
import collections
a = [
[
{'DESCRIP': '', 'INTF': 'Vl77', 'PROTOCOL': 'up', 'STATUS': 'up'},
{'DESCRIP': '', 'INTF': 'Fa0', 'PROTOCOL': 'down', 'STATUS': 'admin down'}
],
[
{'INBOUND_ACL': '', 'INTF': 'Vlan77', 'IPADDR': ['192.168.77.11/24'], 'IP_HELPER': [], 'LINK_STATUS': 'up', 'MTU': '1500', 'OUTGOING_ACL': '', 'PROTOCOL_STATUS': 'up', 'VRF': ''},
{'INBOUND_ACL': '', 'INTF': 'FastEthernet0', 'IPADDR': [], 'IP_HELPER': [], 'LINK_STATUS': 'administratively down', 'MTU': '', 'OUTGOING_ACL': '', 'PROTOCOL_STATUS': 'down', 'VRF': ''}
]
]
a_reshaped = [
{re.search(r'\d+', x["INTF"]).group(): x for x in y}
for y in a
]
results = collections.defaultdict(dict)
for c in a_reshaped:
for key, value in c.items():
results[key] = {**results[key], **value}
print(list(results.values()))
或基于setdefault()
为:
import re
a = [
[
{'DESCRIP': '', 'INTF': 'Vl77', 'PROTOCOL': 'up', 'STATUS': 'up'},
{'DESCRIP': '', 'INTF': 'Fa0', 'PROTOCOL': 'down', 'STATUS': 'admin down'}
],
[
{'INBOUND_ACL': '', 'INTF': 'Vlan77', 'IPADDR': ['192.168.77.11/24'], 'IP_HELPER': [], 'LINK_STATUS': 'up', 'MTU': '1500', 'OUTGOING_ACL': '', 'PROTOCOL_STATUS': 'up', 'VRF': ''},
{'INBOUND_ACL': '', 'INTF': 'FastEthernet0', 'IPADDR': [], 'IP_HELPER': [], 'LINK_STATUS': 'administratively down', 'MTU': '', 'OUTGOING_ACL': '', 'PROTOCOL_STATUS': 'down', 'VRF': ''}
]
]
a_reshaped = [
{re.search(r'\d+', x["INTF"]).group(): x for x in y}
for y in a
]
results = {}
for c in a_reshaped:
for key, value in c.items():
results[key] = {**results.setdefault(key, {}), **value}
print(list(results.values()))
两者都会给你:
[
{'DESCRIP': '', 'INTF': 'Vlan77', 'PROTOCOL': 'up', 'STATUS': 'up', 'INBOUND_ACL': '', 'IPADDR': ['192.168.77.11/24'], 'IP_HELPER': [], 'LINK_STATUS': 'up', 'MTU': '1500', 'OUTGOING_ACL': '', 'PROTOCOL_STATUS': 'up', 'VRF': ''},
{'DESCRIP': '', 'INTF': 'FastEthernet0', 'PROTOCOL': 'down', 'STATUS': 'admin down', 'INBOUND_ACL': '', 'IPADDR': [], 'IP_HELPER': [], 'LINK_STATUS': 'administratively down', 'MTU': '', 'OUTGOING_ACL': '', 'PROTOCOL_STATUS': 'down', 'VRF': ''}
]
你能帮我解决这个简单的问题吗,不幸的是我不明白。
我有一个列表和另外两个带有字典列表的列表(但它可以是更多列表)。
a = [
[
{'DESCRIP': '', 'INTF': 'Vl77', 'PROTOCOL': 'up', 'STATUS': 'up'},
{'DESCRIP': '', 'INTF': 'Fa0', 'PROTOCOL': 'down', 'STATUS': 'admin down'}
],
[
{'INBOUND_ACL': '', 'INTF': 'Vlan77', 'IPADDR': ['192.168.77.11/24'], 'IP_HELPER': [], 'LINK_STATUS': 'up', 'MTU': '1500', 'OUTGOING_ACL': '', 'PROTOCOL_STATUS': 'up', 'VRF': ''},
{'INBOUND_ACL': '', 'INTF': 'FastEthernet0', 'IPADDR': [], 'IP_HELPER': [], 'LINK_STATUS': 'administratively down', 'MTU': '', 'OUTGOING_ACL': '', 'PROTOCOL_STATUS': 'down', 'VRF': ''}
]
]
我的目标是获得合并字典的最终列表,该列表由规则导出('合并所有包含 'INTF' 字段且编号相同的字典,在本例中为 77 或 0 ,换句话说按接口号过滤').
像那样
new_dict = [
{'DESCRIP': '', 'PROTOCOL': 'up', 'STATUS': 'up','INBOUND_ACL': '', 'INTF': 'Vlan77', 'IPADDR': ['192.168.77.11/24'], 'IP_HELPER': [], 'LINK_STATUS': 'up','MTU': '1500', 'OUTGOING_ACL': '', 'PROTOCOL_STATUS': 'up', 'VRF': ''},
{'DESCRIP': '', 'PROTOCOL': 'down', 'STATUS': 'admin down','INBOUND_ACL': '', 'INTF': 'FastEthernet0', 'IPADDR': [], 'IP_HELPER': [], 'LINK_STATUS': 'administratively down', 'MTU': '', 'OUTGOING_ACL': '', 'PROTOCOL_STATUS': 'down', 'VRF': ''}
]
由于我们希望根据键合并 dicts
,我认为最好的起点是重塑我们的数据以促进基于键的查找。在重塑数据的同时,我们还要创建一个仅包含数字的键。
import re
a_reshaped = [
{re.search(r'\d+', x["INTF"]): x for x in y}
for y in a
]
print(a_reshaped )
这会给我们:
[
{
'77': {'DESCRIP': '', 'INTF': 'Vl77', 'PROTOCOL': 'up', 'STATUS': 'up'},
'0': {'DESCRIP': '', 'INTF': 'Fa0', 'PROTOCOL': 'down', 'STATUS': 'admin down'}
},
{
'77': {'INBOUND_ACL': '', 'INTF': 'Vlan77', 'IPADDR': ['192.168.77.11/24'], 'IP_HELPER': [], 'LINK_STATUS': 'up', 'MTU': '1500', 'OUTGOING_ACL': '', 'PROTOCOL_STATUS': 'up', 'VRF': ''},
'0': {'INBOUND_ACL': '', 'INTF': 'FastEthernet0', 'IPADDR': [], 'IP_HELPER': [], 'LINK_STATUS': 'administratively down', 'MTU': '', 'OUTGOING_ACL': '', 'PROTOCOL_STATUS': 'down', 'VRF': ''}
}
]
此时我们可以迭代a_reshaped
并根据键合并字典。我们可以将此部分基于 setdefault()
或 collections.defaultdict()
。我自己更喜欢第二种。
import collections
results = collections.defaultdict(dict)
for c in a_reshaped:
for key, value in c.items():
results[key] = {**results[key], **value}
print(list(results.values()))
给我们:
[
{'DESCRIP': '', 'INTF': 'Vlan77', 'PROTOCOL': 'up', 'STATUS': 'up', 'INBOUND_ACL': '', 'IPADDR': ['192.168.77.11/24'], 'IP_HELPER': [], 'LINK_STATUS': 'up', 'MTU': '1500', 'OUTGOING_ACL': '', 'PROTOCOL_STATUS': 'up', 'VRF': ''},
{'DESCRIP': '', 'INTF': 'FastEthernet0', 'PROTOCOL': 'down', 'STATUS': 'admin down', 'INBOUND_ACL': '', 'IPADDR': [], 'IP_HELPER': [], 'LINK_STATUS': 'administratively down', 'MTU': '', 'OUTGOING_ACL': '', 'PROTOCOL_STATUS': 'down', 'VRF': ''}
]
基于collections.defaultdict()
的完整解决方案是:
import re
import collections
a = [
[
{'DESCRIP': '', 'INTF': 'Vl77', 'PROTOCOL': 'up', 'STATUS': 'up'},
{'DESCRIP': '', 'INTF': 'Fa0', 'PROTOCOL': 'down', 'STATUS': 'admin down'}
],
[
{'INBOUND_ACL': '', 'INTF': 'Vlan77', 'IPADDR': ['192.168.77.11/24'], 'IP_HELPER': [], 'LINK_STATUS': 'up', 'MTU': '1500', 'OUTGOING_ACL': '', 'PROTOCOL_STATUS': 'up', 'VRF': ''},
{'INBOUND_ACL': '', 'INTF': 'FastEthernet0', 'IPADDR': [], 'IP_HELPER': [], 'LINK_STATUS': 'administratively down', 'MTU': '', 'OUTGOING_ACL': '', 'PROTOCOL_STATUS': 'down', 'VRF': ''}
]
]
a_reshaped = [
{re.search(r'\d+', x["INTF"]).group(): x for x in y}
for y in a
]
results = collections.defaultdict(dict)
for c in a_reshaped:
for key, value in c.items():
results[key] = {**results[key], **value}
print(list(results.values()))
或基于setdefault()
为:
import re
a = [
[
{'DESCRIP': '', 'INTF': 'Vl77', 'PROTOCOL': 'up', 'STATUS': 'up'},
{'DESCRIP': '', 'INTF': 'Fa0', 'PROTOCOL': 'down', 'STATUS': 'admin down'}
],
[
{'INBOUND_ACL': '', 'INTF': 'Vlan77', 'IPADDR': ['192.168.77.11/24'], 'IP_HELPER': [], 'LINK_STATUS': 'up', 'MTU': '1500', 'OUTGOING_ACL': '', 'PROTOCOL_STATUS': 'up', 'VRF': ''},
{'INBOUND_ACL': '', 'INTF': 'FastEthernet0', 'IPADDR': [], 'IP_HELPER': [], 'LINK_STATUS': 'administratively down', 'MTU': '', 'OUTGOING_ACL': '', 'PROTOCOL_STATUS': 'down', 'VRF': ''}
]
]
a_reshaped = [
{re.search(r'\d+', x["INTF"]).group(): x for x in y}
for y in a
]
results = {}
for c in a_reshaped:
for key, value in c.items():
results[key] = {**results.setdefault(key, {}), **value}
print(list(results.values()))
两者都会给你:
[
{'DESCRIP': '', 'INTF': 'Vlan77', 'PROTOCOL': 'up', 'STATUS': 'up', 'INBOUND_ACL': '', 'IPADDR': ['192.168.77.11/24'], 'IP_HELPER': [], 'LINK_STATUS': 'up', 'MTU': '1500', 'OUTGOING_ACL': '', 'PROTOCOL_STATUS': 'up', 'VRF': ''},
{'DESCRIP': '', 'INTF': 'FastEthernet0', 'PROTOCOL': 'down', 'STATUS': 'admin down', 'INBOUND_ACL': '', 'IPADDR': [], 'IP_HELPER': [], 'LINK_STATUS': 'administratively down', 'MTU': '', 'OUTGOING_ACL': '', 'PROTOCOL_STATUS': 'down', 'VRF': ''}
]