Python 在字典中查找混合类型值的重复项
我想在字典中识别和分组重复的值。为此,我为我的数据集构建了一个伪哈希(更好的读取签名),如下所示:Python 在字典中查找混合类型值的重复项,python,dictionary,hash,pickle,Python,Dictionary,Hash,Pickle,我想在字典中识别和分组重复的值。为此,我为我的数据集构建了一个伪哈希(更好的读取签名),如下所示: from pickle import dumps taxonomy = {} binder = defaultdict(list) for key, value in ds.items(): signature = dumps(value) taxonomy[signature] = value binder[signature].append(key) 有关具体用
from pickle import dumps
taxonomy = {}
binder = defaultdict(list)
for key, value in ds.items():
signature = dumps(value)
taxonomy[signature] = value
binder[signature].append(key)
有关具体用例,请参见此
不幸的是,我意识到如果以下语句是真的
:
>>> ds['key1'] == ds['key2']
True
这一点不再总是True
:
>>> dumps(ds['key1']) == dumps(ds['key2'])
False
我注意到转储输出上的键顺序对于两个dict都不同。如果我将ds['key1']
和ds['key2']
的输出复制/粘贴到新词典中,我可以成功地进行比较
作为一种过度的替代方法,我可以递归遍历我的数据集,并将dict
实例替换为orderedict
:
import copy
def faithfulrepr(od):
od = od.deepcopy(od)
if isinstance(od, collections.Mapping):
res = collections.OrderedDict()
for k, v in sorted(od.items()):
res[k] = faithfulrepr(v)
return repr(res)
if isinstance(od, list):
for i, v in enumerate(od):
od[i] = faithfulrepr(v)
return repr(od)
return repr(od)
>>> faithfulrepr(ds['key1']) == faithfulrepr(ds['key2'])
True
我担心这种幼稚的做法,因为我不知道我是否涵盖了所有可能的情况
我还可以使用其他(通用)替代方案吗?首先要删除对
deepcopy
的调用,这是您的瓶颈:
def faithfulrepr(ds):
if isinstance(ds, collections.Mapping):
res = collections.OrderedDict(
(k, faithfulrepr(v)) for k, v in sorted(ds.items())
)
elif isinstance(ds, list):
res = [faithfulrepr(v) for v in ds]
else:
res = ds
return repr(res)
然而,sorted
和repr
有其缺点:
faithfulrepr
,并将对象与\uuuuueq\uuuuu
进行比较:
binder, values = [], []
for key, value in ds.items():
try:
index = values.index(value)
except ValueError:
values.append(value)
binder.append([key])
else:
binder[index].append(key)
grouped = dict(zip(map(tuple, binder), values))
因此,您希望每个
dict
的repr
相同。。。有什么原因不能只加载它们并进行比较吗?是的,使用repr
比使用pickle
容易得多。不幸的是,repr
对象并不总是足以比较两个实例的内容。这就是说,repr(ds['key1'])==repr(ds['key2'])
也会返回False
…我的意思是-你想让dict
对象的一些表示比较相等-可以是JSON/pickled/str
'd/repr
'd等等。。。为什么不把它倒过来再比较一下呢?例如:loads(dumps(ds['key1'])==loads(dumps(ds['key2'])
?如果你看我在binder[signature].append(key)
附近的例子,我并没有像a==b
那样比较我的字典。因此,在我的示例中,您的解决方案不起作用。