我正在尝试在列表中提取所有词典的集合,以便dict1 is dict2 == False
为集合中的任何两个词典。使用set()
无法将字典列表缩减为集合,因为它们不可清除。我意识到我可以做到以下几点:
dictlist = [.....]
setlist = []
for d in dictlist:
if all(s is not d for s in setlist):
setlist.append(d)
是否有一个内置的python(使用c,速度更快)类似于set()来减少列表,只是不需要hashable?
答案 0 :(得分:6)
如果您想比较身份,请为每个词典存储id()
function的结果:
seen = set()
unique = [d for d in dictlist if id(d) not in seen and not seen.add(id(d))]
或
unique = {id(d): d for d in dictlist}.values()
这消除了基于对象标识的重复,而不是内容的相等。第一种形式维持秩序,第二种形式不维持(如set()
)。
对于相等,键值对的序列是可哈希的(如果所有值都是可哈希的);其中frozenset()
作为测试内容唯一性的关键:
seen = set()
hashable = lambda d: frozenset(d.items())
unique = [d for d in dictlist if hashable(d) not in seen and not seen.add(hashable(d))]
订单保留列表或:
unique = {frozenset(d.items()): d for d in dictlist}.values()
如果订单不重要。
答案 1 :(得分:0)
由于您关心的是身份而不是值,因此您需要一个身份集。没有内置的标识集(或标识字典),部分原因是它很容易以合理的性能自己构建一个:
dictlist = [.....]
iddict = {}
for d in dictlist:
if id(d) not in iddict:
iddict[id(d)] = d
您想要的词组是iddict.values()
。它不保留dictlist
的顺序,但由于你要求set
类似物,我认为这没问题。