我有一个包含一些对象的迭代器,并想创建一个唯一用户集合,其中每个用户仅列出一次。所以我试着用列表和字典来实现:
>>> for m in ms: print m.to_user # let's first look what's inside ms
...
Pete Kramer
Pete Kramer
Pete Kramer
>>>
>>> uniqueUsers = [] # Create an empty list
>>> for m in ms:
... if m.to_user not in uniqueUsers:
... uniqueUsers.append(m.to_user)
...
>>> uniqueUsers
[Pete Kramer] # This is what I would expect
>>>
>>> uniqueUsers = {} # Now let's create a dict
>>> for m in ms:
... if m.to_user not in uniqueUsers:
... uniqueUsers[m.to_user] = 1
...
>>> uniqueUsers
{Pete Kramer: 1, Pete Kramer: 1, Pete Kramer: 1}
那么我通过将字典转换为列表来测试它,在执行if语句时这样做是有效的,而且它工作得正常:
>>> uniqueUsers = {}
>>> for m in ms:
... if m.to_user not in list(uniqueUsers):
... uniqueUsers[m.to_user] = 1
...
>>> uniqueUsers
{Pete Kramer: 1}
我可以通过测试 uniqueUsers.keys()
来获得类似的结果。
问题是我不理解为什么会出现这种差异。我一直认为如果你执行if object in dict
,它只是创建一个字典键的列表并对其进行测试,但显然情况并非如此。
有人能解释一下object in dict
内部工作原理,并解释为什么它的行为与object in list
不同(正如我所期望的那样)吗?
__eq__
的实现不一致。 - poketo_user
和主类的?Python 字典不会保留重复对象,因为它们具有相同的__hash__
值,但如果您从一个类创建多个实例,每次都会得到一个具有不同哈希值的新对象(由于它们具有相同的表示),但是在字典中的结果不会是表示,因为它们是相同的字符串,因此具有相同的哈希值。 - Mazdak__eq__
实现。这意味着如果没有实现,__hash__
将返回None
,使对象无法哈希化。 - poke__hash__
不会引发错误。)我假设你是在用Python2。 - aneroid__eq__
的实现不一致;所以这部分仍然是正确的。请注意,我的评论是回复另一个评论的,该评论说没有__hash__
实现。 - poke