我创建了一个字典,
d = {'a': 1, 'b': 2, 'c': 3, 'f': 6}
当我在其值上使用 dir
时,
print(dir(d.values()))
它给出了,
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__',
'__ge__', '__getattribute__', '__gt__', '__hash__', '__init__',
'__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__ne__',
'__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
'__sizeof__', '__str__', '__subclasshook__']
但是 __ge__
应该如何使用呢? (同样,__gt__
、__le__
、...)
就像我做的那样,
e = {'w': 5, 'x': 6, 'y': 7, 'z': 8}
print(d.values() >= e.values())
它给出了,
TypeError: '>=' not supported between instances of 'dict_values' and 'dict_values'
如果我将 dict_values
与 dict
或 set
或 list
或 ... 进行比较,则会出现类似的错误。
用 d.keys()
进行类似的实验给出了结果,
print(d.keys() >= e.keys())
给予,
False
如果我改变了,
e = {1: 2, 3: 4, 5: 6}
print(d.keys() >= e.keys())
给予,
False
但它不应该引发错误,将字符串与 int 进行比较,而且 len(d.keys())
不等于 len(e.keys())
?
最佳答案
我认为主要原因是 Dictionary View Objects 下的文档中提到的内容:
Keys views are set-like since their entries are unique and hashable. If all values are hashable, so that (key, value) pairs are unique and hashable, then the items view is also set-like. (Values views are not treated as set-like since the entries are generally not unique.) For set-like views, all of the operations defined for the abstract base class collections.abc.Set are available (for example, ==, <, or ^).
现在 collections.abc.Set 的文档除了提到支持哪些操作之外并没有真正解释任何内容,所以我查看了 dictobject.c source code . dictview_richcompare
是为字典 View 定义操作的地方,在某些类型和边缘情况之后,主要逻辑依赖于两个 View 的长度以及一个 View 是否包含在另一个 View 中(即子集):
ok = 0;
switch(op) {
case Py_NE:
case Py_EQ:
if (len_self == len_other)
ok = all_contained_in(self, other);
if (op == Py_NE && ok >= 0)
ok = !ok;
break;
case Py_LT:
if (len_self < len_other)
ok = all_contained_in(self, other);
break;
case Py_LE:
if (len_self <= len_other)
ok = all_contained_in(self, other);
break;
case Py_GT:
if (len_self > len_other)
ok = all_contained_in(other, self);
break;
case Py_GE:
if (len_self >= len_other)
ok = all_contained_in(other, self);
break;
}
/* Return 1 if self is a subset of other, iterating over self;
0 if not; -1 if an error occurred. */
static int
all_contained_in(PyObject *self, PyObject *other)
为键、值和项定义的 PyTypeObject
dictview_richcompare
被传递给 PyDictKeys_Type
和 PyDictItems_Type
,但是为 PyDictValues_Type
传递了 0
。所以它甚至没有插入与其他两个 View 相同的比较方法。
我真的无法在文件中找到任何关于为什么值被排除的评论,所以我假设它再次与文档中提到的“唯一且可散列”属性相关。即使从直觉上看,在没有键的情况下基于子集比较值也没有多大意义。
https://stackoverflow.com/questions/71786915/