两个dict和一个列表值的任何项的相等性



如果我有像这样的字典

a = {"param1": [1,2,3], "param2": "aaa", "param3": ["a", "b", "c"]}
b = {"param1": [1], "param2": "aaa", "param3": ["b", "c"]}

我需要验证它们是否相等,并忽略大小写敏感度返回true或false,如果任何dict键都有列表值,并且项目中的任何列表都在第二个列表中,它也可以给出true这个例子应该给出真正的

我已经试过了:

shared_headers = {
k: a[k]
for k in a
if k in b and (str(a[k])).lower() == (str(b[k])).lower()
}
return len(shared_headers) == len(a))

但只有当dicts没有列表值,或者我只是列表完全相等并且具有相同的项目时,它才能正常工作

我想这就是你的意思:

def is_equivalent(a, b):
if a.keys() != b.keys():
return False
for k in a:
v1 = a[k]
v2 = b[k]
if isinstance(v1, str) and isinstance(v2, str):
if v1.lower() != v2.lower():
return False
elif isinstance(v1, list) and isinstance(v2, list):
found = False
for x in v1:
for y in v2:
try:
if x.lower() == y.lower():
found = True
break
except AttributeError:
if x == y:
found = True
break
if not found:
return False
elif type(v1) == type(v2):
if v1 != v2:
return False
else:
return False
return True

d1 = {"param1":[1,2,3],"param2":"aaa","param3":["a","b","c"]}
d2 = {"param1":[1],"param2":"aaa","param3":["b","c"]}
is_equivalent(d1, d2)

注意:如果一个值不是字符串或列表类型,则将这两个值与!=进行比较,如果它们不相等,则函数返回False。这不是描述的一部分,但被认为是有意的。

def is_equivalent(a, b):
if a.keys() != b.keys():
return False
for k in a:
v1, v2 = a[k], b[k]
# If they're not both str or list, or they're not the same type~
if (not all(isinstance(x, (str, list)) for x in (v1, v2))
or type(v1) != type(v2)):
return False
# We already know they're the same type, so str test one and then see if equal~
elif isinstance(v1, str) and v1.lower() != v2.lower():
return False
# Otherwise they're lists, and you want to know if v1 is a superset of v2~
elif not set(v1).issuperset(v2):
return False
return True
>>> is_equivalent(a,b)
True

首先,让我们编写一个函数,通过对all的两次调用来实现您所描述的列表等价类型。

def list_equiv(lst1, lst2):
return all(x in lst2 for x in lst1) or 
all(x in lst1 for x in lst2)

然后,我们可以在单个布尔表达式中实现此检查。海象运算符(:=(需要Python 3.8或更高版本。这在很大程度上依赖于A if cond else B语法来确定两个对应的字典值是字符串、列表还是其他值。

def equiv(d1, d2):
return (d1k := d1.keys()) == d2.keys() and 
all(d1[k].lower() == d2[k].lower() if isinstance(d1[k], str) and 
isinstance(d2[k], str) else 
list_equiv(d1[k], d2[k]) if isinstance(d1[k], list) and 
isinstance(d2[k], list) else 
False 
for k in d1k)

您可以很容易地将列表等效性检查内联到equiv函数中。

def equiv(d1, d2):
return (d1k := d1.keys()) == d2.keys() and 
all(d1[k].lower() == d2[k].lower() 
if isinstance(d1[k], str) and 
isinstance(d2[k], str) else 
all(x in d2[k] for x in d1[k]) or 
all(x in d1[k] for x in d2[k]) 
if isinstance(d1[k], list) and 
isinstance(d2[k], list) else 
False 
for k in d1k)

最新更新