python - `__ge__` 在 dict.values() 上使用时失败

我创建了一个字典,

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_valuesdictsetlist 或 ... 进行比较,则会出现类似的错误。

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_TypePyDictItems_Type,但是为 PyDictValues_Type 传递了 0。所以它甚至没有插入与其他两个 View 相同的比较方法。

我真的无法在文件中找到任何关于为什么值被排除的评论,所以我假设它再次与文档中提到的“唯一且可散列”属性相关。即使从直觉上看,在没有键的情况下基于子集比较值也没有多大意义。

https://stackoverflow.com/questions/71786915/

相关文章:

android - 我无法将 Android 项目从 Delphi 10.4 迁移到 Delphi

c# - 使用 EF Core 按 Id 检索实体的通用方法

node.js - Remix.run 不使用 node.js 作为后端吗?

c - 在格式控制字符串中使用消息

c - 你怎么能告诉计算机它正在添加而没有 addl 在程序集中

c++ - 临时初始化和引用初始化

java - 如何使用 Collectors.collectionAndThen 和 Collect

authentication - 是 CQRS 中的登录/注册命令或查询

python - 将列表附加到现有数据框

haskell - 在 Haskell 中日志记录功能的不同实现之间切换的有效方法?