gpt4 book ai didi

python - 以简单易读的方式过滤字典

转载 作者:太空宇宙 更新时间:2023-11-03 14:50:01 26 4
gpt4 key购买 nike

使用 python3.4 我正在尝试过滤导出为 JSON 并转换为字典的防火墙规则库。我想根据用户定义的标准进行过滤,但我似乎无法做到这一点,除非具有大量循环和 if 语句的难以阅读的结构。

来 self 的防火墙条目的字典非常大,所以我将它们缩短了一点。

2 个例子:

entry1 = {'action': 'accept',
'dstintf': [{'name': 'ZN_HDW', 'q_origin_key': 'ZN_HDW'}],
'srcintf': [{'name': 'ZN_AUDIT', 'q_origin_key': 'ZN_AUDIT'}]
}
entry2 = {'action': 'accept',
'dstintf': [{'name': 'ZN_HDW', 'q_origin_key': 'ZN_HDW'}],
'srcintf': [{'name': 'ZN_DMZ', 'q_origin_key': 'ZN_DMZ'},
{'name': 'ZN_MGMT', 'q_origin_key': 'ZN_MGMT'},
{'name': 'ZN_AUDIT', 'q_origin_key': 'ZN_AUDIT'}]
}

我想创建一个数据结构来与 2 个示例进行比较并创建如下:

filter = {'action': 'accept',
'srcintf': [{'name': 'ZN_AUDIT', 'q_origin_key': 'ZN_AUDIT'}]
}

在搜索了如何比较这些结构之后,我得到了一些可读的代码。我的问题是它在 entry2(具有多个源接口(interface))上的计算结果不为真:

>>> filter.items() <= entry1.items()
True
>>> filter.items() <= entry2.items()
False

关于如何执行此操作的任何提示?

编辑:使用下面 Eric Duminil 的回答我可以创建一些东西(见下文),尽管它仍然不如我想要的那样可读。还有其他提示吗?

example = entry2
# Compare entry to filter
noMatch = 0
for key in filter:
if isinstance(example[key], list):
# Convert list of dicts to list for easier comparing
tmpExample = [d['name'] for d in example[key]]
# Break if entry does not contain all criteria
if not all(value in tmpExample for value in filter[key]):
noMatch = 1
print("No match on: " + str(filter[key]))
break
elif filter[key] != example[key]:
# Simple string comparing
noMatch = 1
print("No match on: " + str(filter[key]))
break

if noMatch == 0:
print("Match")
else:
print(" No match")

最佳答案

理论

里面的数据结构'dstintf''srcintf'不会让这个问题更容易。字典列表几乎永远不是正确的类型。

根据您的需要,您可能应该将其转换为字典:

>>> data = [{'name': 'ZN_DMZ', 'q_origin_key': 'ZN_DMZ'},
... {'name': 'ZN_MGMT', 'q_origin_key': 'ZN_MGMT'},
... {'name': 'ZN_AUDIT', 'q_origin_key': 'ZN_AUDIT'}]
>>> {d['q_origin_key']:d['name'] for d in data}
{'ZN_AUDIT': 'ZN_AUDIT', 'ZN_MGMT': 'ZN_MGMT', 'ZN_DMZ': 'ZN_DMZ'}

但是如果 name 的值和 q_origin_key总是相等的,你可以只使用列表或集合:

>>> [d['name'] for d in data]
['ZN_DMZ', 'ZN_MGMT', 'ZN_AUDIT']
>>> {d['name'] for d in data}
set(['ZN_AUDIT', 'ZN_MGMT', 'ZN_DMZ'])

现在应该更容易过滤数据,没有循环或 if

最后,dict.items()以任意顺序返回元组列表。

我不认为dict1.items() <= dict2.items()会帮你做任何事情。

例子

将您的代码拆分为多个函数并使用集合可能是个好主意:

query = {'action': 'accept',
'srcintf': [{'name': 'ZN_AUDIT', 'q_origin_key': 'ZN_AUDIT'}]
}

entry1 = {'action': 'accept',
'dstintf': [{'name': 'ZN_HDW', 'q_origin_key': 'ZN_HDW'}],
'srcintf': [{'name': 'ZN_AUDIT', 'q_origin_key': 'ZN_AUDIT'}]
}

entry2 = {'action': 'accept',
'dstintf': [{'name': 'ZN_HDW', 'q_origin_key': 'ZN_HDW'}],
'srcintf': [{'name': 'ZN_DMZ', 'q_origin_key': 'ZN_DMZ'},
{'name': 'ZN_MGMT', 'q_origin_key': 'ZN_MGMT'},
{'name': 'ZN_AUDIT', 'q_origin_key': 'ZN_AUDIT'}]
}


def compare_values(value1, value2):
if isinstance(value1, list) and isinstance(value2, list):
return set(d['name'] for d in value1).issubset(set(d['name'] for d in value2))
else:
return value1 == value2

def is_a_match(query, entry):
do_not_match = [key for key in query if not compare_values(
query[key], entry.get(key))]
for key in do_not_match:
print("%r does not match" % key)
return len(do_not_match) == 0

print(is_a_match(query, entry1))
# True
print(is_a_match(query, entry2))
# True
print(is_a_match({'action': 'decline'}, entry2))
# 'action' does not match
# False

关于python - 以简单易读的方式过滤字典,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46545000/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com