在Python中迭代字典时,为什么必须调用.items()方法?

9 浏览
0 Comments

在Python中迭代字典时,为什么必须调用.items()方法?

为什么在字典中遍历键值对时要调用 items() 方法?例如:

dic = {'one': '1', 'two': '2'}
for k, v in dic.items():
    print(k, v)

为什么字典默认的迭代行为不是这样的呢?

for k, v in dic:
    print(k, v)

0
0 Comments

在Python中,当遍历字典时,为什么要调用.items()方法呢?这个问题的出现是因为Python对于不同的容器有着不同的期望。对于任何容器C来说,我们期望以下代码能够通过断言:

for item in C:
    assert item in C

如果for循环中的in关键字与容器中的in操作有着完全不同的含义,你会感到惊讶吗?对于列表、集合、元组等容器来说,它们的行为符合我们的期望。

因此,当容器C是一个字典时,如果在for循环中的in操作能够返回键/值元组,那么根据最小惊讶原则,in操作在包含性检查时也必须接受一个键/值元组作为左操作数。

但是,这样做有多大的用处呢?实际上并没有多大用处,反而会使得if (key, value) in C成为if C.get(key) == value的同义词。而我相信,与if k in C实际上的含义(仅检查键的存在并忽略值)相比,我可能只有100分之一的需求来执行或者希望执行这样的检查。

另一方面,只想遍历键是非常常见的,例如:

for k in thedict:
    thedict[k] += 1

如果还有值的话,并没有什么帮助:

for k, v in thedict.items():
    thedict[k] = v + 1

实际上这种写法更加复杂和冗长。(需要注意的是,items是最初用于获取键/值对的方法的拼写方式:不幸的是,在那个时候,这样的访问器返回整个列表,所以为了支持“仅迭代”操作,引入了另一种拼写方式,即iteritems,在Python 3中,由于与以前的Python版本的向后兼容性约束大大减弱,它再次变成了items)。

0
0 Comments

为什么在Python中迭代字典时必须调用.items()方法呢?

我猜测:使用完整的元组对于循环来说可能更直观,但对于使用'in'来测试成员身份可能不太直观。

如果必须同时指定键和值才能使用'in',那么上述代码就不能正常工作。我很难想象出一个这样的用例,即检查字典中是否同时存在键和值。只测试键是更自然的。

那么,什么时候你会写出这样的条件呢?

现在,在'in'运算符和'for ... in'操作的项上没有必要是相同的。从实现上来说,它们是不同的操作(__contains__ vs. __iter__)。但是这种小的不一致性可能会有些令人困惑和不一致。

考虑到我所能想到的每一种内置可迭代类型,只有当'x'在某一点上等于'foo'中的'i'时,'x in foo'才为真,这将是一个非常大的不一致性。

解决方法:调用.items()方法可以将字典转换为一个包含键值对的元组列表,然后可以使用'for ... in'进行迭代。这样可以保持一致性,并且更容易理解和使用。

0