考虑一些包含简单类型的 python 对象,如 strings/unicode 、整数、
列表,字典。
a = { 'name': 'John'}
b = {'name':'Mathew'}
c = {'name':345}
这里a在结构上与b相似,但与c不同,因为c中的值是一个整数。
更复杂的例子:
a = { 'candidates': [ {'name':'John','age':23},{'name':'Matt','age':23}],'class':{'num':4,'year':2005}}
b = { 'candidates': [ {'name':'Mary','age':33},{'name':'Skipper','age':24}],'class':{'num':14,'year':2006}}
虽然 a 和 b 具有不同的值,但它们在相同的键上具有相同类型的值,这也适用于嵌套值。
找到两个这样的 python 对象相似的好方法是什么?
假设列表将具有统一类型的元素。
我想到的一个想法是递归地比较对象成员的类型
。
我想知道是否有更简单的 hack 或 python 模块可以做到这一点?
一个解决方案确实是一个比较类型的递归解决方案:
def compare(v1, v2):
if not type(v1) == type(v2):
return False
if isinstance(v1, dict):
return compare(sorted(v1.items()), sorted(v2.items()))
elif isinstance(v1, (list, tuple)):
if not len(v1) == len(v2):
return False
return all(compare(a, b) for a, b in zip(v1, v2))
return True
此功能适用于您发布的所有案例。但是,如果任何列表在结构之间的长度不同,它将始终返回 False。以下是一些结果:
>>> compare({'name':'Mathew'}, {'name':'John'})
True
>>> compare({'name':'Mathew'}, {'name':2})
False
>>> compare([1, 1], [2, 2])
True
>>> compare([1, 2], [1])
False
>>> compare([1, "a"], [2, "b"])
True
如果你想让第四个通过,你可以分离出列表子句并只比较第一个项目,这也假设空列表具有正确的类型:
elif isinstance(v1, list):
if (not v1) or (not v2):
return True
return compare(v1[0], v2[0])
在使用像 python 这样动态的语言中执行此类操作时,您必须非常小心。如果您的输入与您期望的结构略有不同,很容易得到“错误”的结果。例如,如果结构包含集合,则它们只会在类型上进行比较,而不会在内容上进行比较。