我正在尝试排序和比较包含compute MFQAPsum=sum(!MyVars).
中词典和其他数据列表的词典。我不确定比较两者的最佳方法。两个词典中的数据是相同的,但我无法控制它们的给定顺序。数据如下所示:
Python 3.6
我正在尝试与dict_A = {
'addresses': [
{'address': 'Tribal Land', 'address_country': 'AB', 'city': None, 'postal_code': None, 'state': 'GY'},
{'address': 'Userland', 'address_country': 'ND', 'city': None, 'postal_code': None, 'state': 'KY'}],
'name': 'FooBar',
'dob': None,
'ids':[
{'date': None, 'country': None, 'number': 'Male', 'type': 'Gender', 'location': 'USA'},
{'date': None, 'country': 'VE', 'number': '1234567', 'type': 'Foo No.', 'location': 'USA'}]
}
dict_B = {
'addresses': [
{'address': 'Userland', 'address_country': 'ND', 'city': None, 'postal_code': None, 'state': 'KY'},
{'address': 'Tribal Land', 'address_country': 'AB', 'city': None, 'postal_code': None, 'state': 'GY'}],
'dob': None,
'id':[
{'country': 'VE', 'date': None, 'type': 'Foo No.', 'location': 'USA', 'number': '1234567'},
{'country': None, 'date': None, 'type': 'Gender', 'location': 'USA', 'number': 'Male'}],
'name': 'FooBar'
}
评估dict_A == dict_B
进行比较。
我试图遍历字典,将项目发送到Pandas并将True
设置为dict
,但这似乎不起作用。我不确定最好的方法。
ordered_dict
也许更好的方法是将字典设置为列表,并以这种方式进行比较?
答案 0 :(得分:1)
因此,如果您拥有列表和词典,则可以在每个列表和词典上调用自定义相等的方法。例如,
def list_equal(l1, l2):
if type(l1[0]) is dict:
if len(l1) != len(l2):
return False
for i in range(len(l1)):
if not l1.count(l1[i]) == l2.count(l1[i]):
return False
return True
return sorted(l1) == sorted(l2)
然后
def structures_equal(s1, s2):
if not sorted(list(set(s1.keys()))) == sorted(list(set(s2.keys()))):
return False
for key in s1:
if type(s1[key]) is list:
if not type(s2[key]) is list:
return False
elif not list_equal(s1[key], s2[key]):
return False
elif not s1[key] == s2[key]:
return False
return True
现在列表比较在O(n ^ 2)中运行,因为它计算每行的实例。如果从同一数据源获取这些行,那么为每个行提取唯一ID也很有用。然后,时间变得明显更快,因为我们只比较每个列表中的UIDS及其计数。如果你能把它作为UIDS的字典和分配的行的实例数,那就更好了。例如
[{'address': 'address0', 'foo': 'bar0', 'uid': 0},
{'address': 'address1', 'foo': 'bar1', 'uid': 1},
{'address': 'address2', 'foo': 'bar2', 'uid': 2},
{'address': 'address3', 'foo': 'bar3', 'uid': 3},
{'address': 'address4', 'foo': 'bar4', 'uid': 4},
{'address': 'address0', 'foo': 'bar0', 'uid': 0},
{'address': 'address1', 'foo': 'bar1', 'uid': 1},
{'address': 'address2', 'foo': 'bar2', 'uid': 2}]
成为
{0: [{'address': 'address0', 'foo': 'bar0', 'uid': 0},
{'address': 'address0', 'foo': 'bar0', 'uid': 0}],
1: [{'address': 'address1', 'foo': 'bar1', 'uid': 1},
{'address': 'address1', 'foo': 'bar1', 'uid': 1}],
2: [{'address': 'address2', 'foo': 'bar2', 'uid': 2},
{'address': 'address2', 'foo': 'bar2', 'uid': 2}],
3: [{'address': 'address3', 'foo': 'bar3', 'uid': 3}],
4: [{'address': 'address4', 'foo': 'bar4', 'uid': 4}]}
此算法将是
def list_converted_to_dict_equal(d1, d2):
for key in d1:
if key not in d2 or len(d1[key]) != len(d2[key]):
return False
return True
哪个比以前好多了。
答案 1 :(得分:1)
将您的词典转换为数据结构,即真实的类。
对于这个类,如果你想对它们进行排序,请为每个对象重载__cmp__
方法。
如果您希望能够判断两个对象是否相等,则重载__eq__
。
class ApiDto(object):
def __cmp__ (self, other):
pass
def __eq__ (self, other):
pass
class Address(object):
def __cmp__ (self, other):
pass
def __eq__ (self, other):
pass
class Id(object):
def __cmp__ (self, other):
pass
def __eq__ (self, other):
pass
将dicts更改为现在使用上述类。
现在您可以根据需要进行排序和比较,而无需立即处理所有属性。
如果此时不明显,您拥有的词典现在将是ApiDto
,其中name
字段,addresses
字段是{{1}的列表}},Address
字段,是ids
的列表,最后是Id
字段。
当您为dob
重载__cmp__
和__eq__
方法时,您将对所有类执行相同操作,这将允许您对对象进行排序,并最终将它们与每个类进行比较其他
此外,如果您需要将对象转换回dict,可以调用ApiDto
属性来为此提供