#python-3.x #dictionary #arraylist #key #key-value
Вопрос:
Не могли бы вы помочь мне с этой простой вещью, к сожалению, я ее не понимаю.
У меня есть этот список с двумя другими списками со списками диктовок (но это может быть больше списков).
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': ''}
]
Комментарии:
1. Привет, для сообщества важно, чтобы вы продемонстрировали, что вы также работаете над решением своей проблемы. Лучший способ сделать это-включить текстовую версию кода, которую вы используете сейчас, даже если она работает не совсем правильно. Также очень полезно увидеть, чего вы хотите в результате.
2. Если вы хотите подтолкнуть к началу работы, у меня есть решение, основанное на
re.findall()
и илиcollections.defaultdict()
илиsetdefault()
.3. Джонс, мне была бы полезна любая помощь. Я понимаю, что мой вопрос может дублировать некоторые, но я с трудом понимаю, как найти короткое решение =)
Ответ №1:
Поскольку мы хотим объединить 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': ''}
]