dict.items和dict.values之间不一致的行为 [英] Inconsistent behaviour between dict.items and dict.values

查看:99
本文介绍了dict.items和dict.values之间不一致的行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

注意: python3中的代码示例,但问题代表python2 aswell(替换 .keys .viewkeys 等)



dict 对象提供视图方法(有时)支持集合操作:

 >>> {'a':0,'b':1} .keys()& {'a'} 
{'a'}
>>> {'a':0,'b':1} .items()& {('a',0)}
{('a',0)}

但是值视图不支持设置运算符:

 >>> {'a':0,'b':1} .values()& {0} 
追溯(最近的最后一次呼叫):
文件< stdin>,第1行,< module>
TypeError:&:'dict_values'和'set'不支持的操作数类型

我知道一个dict值可以是一个不可哈希的对象,所以并不总是可以创建一组值,但是对于 dict.items 这里,只有在dict 中有一个不可分类的类型,集合操作才会在运行时失败 .items ,而设置操作 .values 立即失败。



该文档提到 值视图不被视为设置,因为条目通常不是唯一的 ,但这似乎不是一个令人信服的原因 - python doesn例如,阻止您创建一个集合文字,如 {0,0,1,2}



行为不一致的真正原因是什么?

解决方案

如果我们 您将使价值词典视图生成非常昂贵的对象。您必须计算所有值的散列,然后才能将其用作集合;你真的不想这样做一个大字典,特别是如果你不知道如果所有的值甚至可以哈希的话。



因此,这是一个明显的操作,如果要将值视为一组,显式将其设置为:

  values = set(yourdict.values())

dict.items() / code>行为源于事实,我们知道密钥至少是唯一的,所以每个(密钥,值)对也是唯一的;在封面下,您可以将成员资格测试委托给密钥字典视图。



但是,一旦您使用集合操作(​​交集,联合等),您正在创建对象,而不是一个二进制视图。而对于这种集合对象,(key,value)对中的两个元素必须可以是哈希的,因为通用 类型不能对键进行相同的假设,也不能保持该约束(如 {'a':0} .items()& {('a' 1)} 是完全合法的,但会导致重复的键)。


Note: code examples in python3, but the question stands for python2 aswell (replacing .keys with .viewkeys, etc)

dict objects provide view methods which (sometimes) support set operations:

>>> {'a': 0, 'b': 1}.keys() & {'a'}
{'a'}
>>> {'a': 0, 'b': 1}.items() & {('a', 0)}
{('a', 0)}

But the values view does not support set operators:

>>> {'a': 0, 'b': 1}.values() & {0}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for &: 'dict_values' and 'set'

I understand that a dict value can be a non-hashable object, so it is not always possible to make a set of the values, however the same is true for dict.items, and here the set operations only fail at runtime for .items once there is an unhashable type in the dict, whereas the set operation for .values fails immediately.

The docs mention that Values views are not treated as set-like since the entries are generally not unique, but this doesn't seem to be a convincing reason - python doesn't for example prevent you from creating a set literal like {0, 0, 1, 2}.

What is the real reason for this inconsistency in behaviour?

解决方案

If we were to treat the values as a set, you'd make the values dictionary view a very costly object to produce. You have to calculate the hash of all values before you can use it as a set; you really don't want to do this for a large dictionary, especially if you don't know up front if all values are even hashable.

As such, this is far better left as an explicit operation; if you want to treat the values as a set, explicitly make it a set:

values = set(yourdict.values())

The dict.items() behaviour stems from the fact that we know up-front that the keys at least are unique, so each (key, value) pair is unique too; under the covers you can delegate membership testing to the keys dictionary view.

But as soon as you use set operations on that (intersection, union, etc.) you are creating a new set object, not a dicitonary view. And for such a set object both elements in the (key, value) pair must be hashable, as the generic set type cannot make the same assumption about the keys, nor could you maintain that constraint (as {'a': 0}.items() & {('a', 1)} is perfectly legal but leads to duplicate keys).

这篇关于dict.items和dict.values之间不一致的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆