是否有内置的python用于从列表中提取不可用对象的“集合”,使用“is”比较?

时间:2013-12-15 10:11:30

标签: python

我正在尝试在列表中提取所有词典的集合,以便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?

2 个答案:

答案 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类似物,我认为这没问题。