gpt4 book ai didi

python - 为字典伪造 __hash__() 的惯用方法是什么?

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

编辑:正如@BrenBarn 指出的那样,原文没有意义。

给定一个字典列表(由 csv.DictReader 提供——它们都有 str 键和值)最好通过全部填充来删除重复项在一个集合中,但这不能直接完成,因为 dict 不可散列。一些existing questions触及如何为集合/字典伪造__hash__(),但没有说明应该首选哪种方式。

# i. concise but ugly round trip
filtered = [eval(x) for x in {repr(d) for d in pile_o_dicts}]

# ii. wordy but avoids round trip
filtered = []
keys = set()
for d in pile_o_dicts:
key = str(d)
if key not in keys:
keys.add(key)
filtered.append(d)

# iii. introducing another class for this seems Java-like?
filtered = {hashable_dict(x) for x in pile_o_dicts}

# iv. something else entirely

本着Zen of Python的精神什么是“显而易见的方法”?

最佳答案

根据您的示例代码,我认为您的问题与您的字面意思略有不同。您实际上并不想覆盖 __hash__()——您只是想在线性时间内过滤掉重复项,对吧?因此,您需要为每个字典确保以下内容:1) 每个键值对都被表示,并且 2) 它们以稳定的顺序表示。您可以使用键值对的排序元组,但我建议使用 frozensetfrozenset 是可散列的,它们避免了排序的开销,这应该会提高性能(正如 this answer 似乎证实的那样)。缺点是它们比元组占用更多的内存,所以这里有一个空间/时间的权衡。

此外,您的代码使用集合来进行过滤,但这没有多大意义。如果您使用字典,就不需要那个丑陋的 eval 步骤:

filtered = {frozenset(d.iteritems()):d for d in pile_o_dicts}.values()

或者在 Python 3 中,假设您想要一个列表而不是字典 View :

filtered = list({frozenset(d.items()):d for d in pile_o_dicts}.values())

这些都有点笨重。为了可读性,考虑将其分成两行:

dict_o_dicts = {frozenset(d.iteritems()):d for d in pile_o_dicts}
filtered = dict_o_dicts.values()

另一种方法是元组的有序元组:

filtered = {tuple(sorted(d.iteritems())):d for d in pile_o_dicts}.values()

最后一点:不要为此使用 repr。评估为相等的字典可以有不同的表示:

>>> d1 = {str(i):str(i) for i in range(300)}
>>> d2 = {str(i):str(i) for i in range(299, -1, -1)}
>>> d1 == d2
True
>>> repr(d1) == repr(d2)
False

关于python - 为字典伪造 __hash__() 的惯用方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12290703/

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