为什么“k in d”为False,而“k in d.keys()”为真?

2024-06-01 00:10:16 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一些python代码抛出keyror异常。到目前为止,我还不能在操作环境之外进行复制,所以我不能在这里发布一个简化的测试用例。在

引发异常的代码在循环中迭代,如下所示:

for k in d.keys():
    if condition:
        del d[k]

del[k]行抛出异常。我在它的周围添加了一个try/except子句,并且能够确定k in d是False,但是{}是真的。在

d的键是老式类实例的绑定方法。在

该类实现了__cmp____hash__,所以这就是我一直关注的地方。在


Tags: 代码infalseforif环境测试用例keys
3条回答

k in d.keys()将迭代测试每个键的相等性,而k in d使用__hash__,因此{}可能被破坏(即,它为比较相等的对象返回不同的哈希值)。在

简单的例子是什么坏了,为了兴趣:

>>> count = 0
>>> class BrokenHash(object):
...     def __hash__(self):
...             global count
...             count += 1
...             return count
...
...     def __eq__(self, other):
...             return True
...
>>> foo = BrokenHash()
>>> bar = BrokenHash()
>>> foo is bar
False
>>> foo == bar
True
>>> baz = {bar:1}
>>> foo in baz
False
>>> foo in baz.keys()
True

不要删除d中的项,迭代时将要删除的键存储在列表中,然后在另一个循环中删除它们:

deleted = []
for k in d.keys():
    if condition:
        deleted.append(k)
for k in deleted:
    del d[k]

相关问题 更多 >