gpt4 book ai didi

python - Python 3.5 在字典中进行比较时选择键的选择

转载 作者:IT老高 更新时间:2023-10-28 20:20:55 24 4
gpt4 key购买 nike

如下构造字典时:

dict = { True: 'yes', 1: 'No'}

当我在交互式 Python 解释器中运行它时,dict 以这种方式表示:

dict = {True: 'No'}

我知道由于类型强制,值 True1 相等,因为在比较数字类型时,缩小的类型会扩大到其他类型( bool 值是整数的 child )。所以我从文档中了解到,当我们输入 True == 1 时,Python 会将 True 转换为 1 并进行比较。

我不明白的是为什么选择 True 作为键而不是 1

我错过了什么?

最佳答案

字典被实现为哈希表,在这里添加键/值时有两个重要概念:哈希平等

为了插入特定的键/值,Python 首先计算键的 hash 值。此哈希值用于确定 Python 应首先尝试放置键/值的表的行。

如果哈希表的行是空的,很好:新的键/值可以插入到字典中,填充空行。

但是,如果该行中已经存在某些内容,则 Python 需要测试键是否相等。如果键相等(使用 ==),那么它们被认为是相同的键,Python 只需要更新该行上的相应值。

(如果键不相等,Python 会查看表中的其他行,直到找到键或到达空行,但这与此问题无关。)


当您编写 {True: 'yes', 1: 'No'} 时,您是在告诉 Python 创建一个新字典,然后用两个键/值对填充它。这些从左到右处理:True: 'yes' 然后 1: 'No'.

我们有 hash(True) 等于 1。键 True 进入哈希表的第 1 行,字符串 'yes' 是它的值(value)。

对于下一对,Python 发现 hash(1) 也是 1,因此查看表的第 1 行。那里已经有了一些东西,所以现在 Python 检查键是否相等。我们有 1 == True 所以 1 被认为是与 True 相同的键,因此其对应的值更改为字符串 '没有'.

这会产生一个包含一个条目的字典:{True: 'No'}


如果您想深入了解 CPython 3.5 的核心内容,了解在 Python 表面层之下创建字典的情况,这里有更多详细信息。

  • Python 代码 {True: 'yes', 1: 'No'} 被解析为标记并提供给编译器。给定语法,Python 知道必须使用大括号内的值创建字典。将四个值加载到虚拟机堆栈(LOAD_CONST)然后构建字典(BUILD_MAP)的字节码排队。

  • 四个常量值按它们出现的顺序被压入栈顶:

    'No'
    1
    'yes'
    True
  • 然后使用参数 2 调用操作码 BUILD_MAP(Python 计算了两个键/值对)。此操作码负责从堆栈上的项目实际创建字典。看起来像 this :

    TARGET(BUILD_MAP) {
    int i;
    PyObject *map = _PyDict_NewPresized((Py_ssize_t)oparg);
    if (map == NULL)
    goto error;
    for (i = oparg; i > 0; i--) {
    int err;
    PyObject *key = PEEK(2*i);
    PyObject *value = PEEK(2*i - 1);
    err = PyDict_SetItem(map, key, value);
    if (err != 0) {
    Py_DECREF(map);
    goto error;
    }
    }

    while (oparg--) {
    Py_DECREF(POP());
    Py_DECREF(POP());
    }
    PUSH(map);
    DISPATCH();
    }

这里的三个关键步骤如下:

  1. 使用 _PyDict_NewPresized 创建一个空的哈希表。小型字典(只有几个项目,在本例中为 2)需要一个有 8 行的表。

  2. 进入 for 循环,从 2(在本例中)开始倒数到 0。PEEK(n)是一个宏,指向堆栈下的第 n 个项目。因此,在循环的第一次迭代中,我们将拥有

PyObject *key = PEEK(2*2);       /* item 4 down the stack */  
PyObject *value = PEEK(2*2 - 1); /* item 3 down the stack */

这意味着 *key 将是 True 并且 *value 将是 'yes' 在第一个依次通过。在第二个它将是 1'No'

  1. PyDict_SetItem在每个循环中调用以将当前的 *key*value 放入字典中。这与编写 dictionary[key] = value 时调用的函数相同。它计算键的哈希值以确定首先在哈希表中查找的位置,然后在需要时将该键与该行上的任何现有键进行比较(如上所述)。

关于python - Python 3.5 在字典中进行比较时选择键的选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37164127/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com