为什么我不能在 python 中使用列表作为字典键?究竟什么可以使用,什么不能使用,为什么?

2023-12-01

我发现以下内容都是有效的:

>>> d = {}
>>> d[None] = 'foo'
>>> d[(1, 3)] = 'baz'

甚至模块也可以用作字典键:

>>> import sys
>>> d[sys] = 'bar'

但是,列表不能,包含列表的元组也不能:

>>> d[[2]] = 'spam'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
>>> d[(1, [3])] = 'qux'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

为什么在元组中存储列表意味着它不能再是字典键?毕竟,我可以轻松地“隐藏”模块内的列表(实际上,例如sys.path已经是一个列表)。

我有一些模糊的想法,即密钥必须是“可散列的”,但我没有详细理解这意味着什么,或者为什么会有这样的限制。如果 Python 允许使用列表作为键,例如使用它们的内存位置作为散列,会出现什么问题?


Python wiki 中有一篇关于该主题的好文章:为什么列表不能作为字典键。正如那里所解释的:

如果 Python 允许使用列表作为键,例如使用它们的内存位置作为散列,会出现什么问题?

这会导致一些意想不到的行为。列表通常被视为它们的值源自其内容的值,例如在检查(不)相等时。许多人会 - 可以理解 - 期望你可以使用任何列表[1, 2]要获得相同的密钥,您必须保留完全相同的列表对象。但是,一旦用作键的列表被修改,按值查找就会中断,并且按身份查找需要跟踪该确切的列表对象 - 这不是使用列表的一般要求。

其他对象,例如模块和object,无论如何,都要从它们的对象标识中进行更大的处理(最后一次你有两个不同的模块对象被称为sys?),并以此进行比较。因此,当它们用作字典键时,在这种情况下也会按身份进行比较,这并不令人惊讶 - 甚至是预期的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么我不能在 python 中使用列表作为字典键?究竟什么可以使用,什么不能使用,为什么? 的相关文章

随机推荐

  • 如何在单选按钮中添加jquery验证红框效果

    如果 jQuery 验证像示例图片中那样激活 我想制作一个红色阴影框 红色边框 有人可以帮我解决这个问题吗 我的代码如下所示 document ready function var month day year for var i 1 i
  • 消除 ggplot y 轴和第一个 x 值之间的间隙

    我需要消除 x 轴上 1950 年之前的间隙 我尝试过使用scale x continuous但这会导致 Error Discrete value supplied to continuous scale 我相信这一定与数据的日期格式有关
  • 单击时确定句子的字符

    在一次随机休息时 我发现自己想知道是否可以使用 jQuery 来确定单击句子中的单个字符 例如 This 当用户第一次点击h jQuery 会将其返回给我 我能想到的唯一方法是将句子中的每个字符用其字母的类别包装在一个跨度中 如下例所示 s
  • Neo4J Cypher - 匹配节点的关系计数

    我正在开发一个小项目 我必须在 Twitter 等用户之间保持关注 我正在尝试进行一个查询 返回某个节点的追随者 我们将其称为 X 节点 因此 查询返回 X 的关注者以及 X 的关注者的关注者计数 以及 X 的关注者关注的节点数 包括该计数
  • 如何使用 HTML/CSS/JavaScript 开发桌面应用程序? [关闭]

    Closed 这个问题需要多问focused 目前不接受答案 首先 我对专业地做这件事不感兴趣 我是一名 Web 开发人员 我的一位同事最近离开 Spotify 并表示他将主要从事 Spotify 桌面应用程序的 JavaScript 工作
  • Ansible 命令模块显示“|”是非法字符

    我正在使用 Ansible 部署我的项目 并尝试检查是否安装了指定的包 但我的任务有问题 以下是任务 name Check if python apt is installed command dpkg l grep python apt
  • PHPMailer字符编码问题

    我尝试使用PHPMailer发送注册 激活 等邮件给用户 require class phpmailer php mail gt charSet UTF 8 mail new PHPMailer mail gt IsSMTP mail gt
  • Angular:我在注入器模块上不断收到此错误

    我正在制作一个有角度的应用程序 它不断出现此错误 未捕获的错误 injector modulerr http errors angularjs org 1 4 9 injector modulerr p0 webinarApp p1 错误
  • 查找迭代器的值类型

    我有一个模板参数InIter在我的一个重载函数中 我需要调用for each n循环使用InIter for x迭代 这对我来说没有任何困难 但我无法获得值类型迭代器的 举个例子 invalid lambda function for ea
  • 我可以将存储库排列到 Github 上的文件夹中吗?

    我是 git 新手 我现在正在做的是将我最近的所有项目作为存储库上传到 github 有很多不同的项目 例如网页设计 WordPress 主题和不同类型的应用程序 其中一些也属于更大的项目 因为它们是将某些东西作为不同的应用程序进行测试 问
  • PowerShell 和 MSDeploy - 带空格的参数

    我无法弄清楚如何使用 msdeploy exe 和 PowerShell v4 传递包含带空格的文件夹的参数 示例 Powershell 脚本 write warning WITHOUT SPACE fl1 d nospace a txt
  • Oracle 中如何判断一个值是否不是数字?

    如果我的值无效 我有以下代码会返回错误消息 如果给定的值不是数字 我想给出相同的错误消息 IF option id 0021 THEN IF value lt 10000 or value gt 7200000 or Numeric Che
  • 下载 ViewVC 公开的 SVN 存储库

    有没有一种简单的方法来下载在网络上公开的 SVN 存储库ViewVC 这个问题有两种解释方式 但简短的回答都是 否 ViewVC 是一个存储库查看器 因此无法通过 Web 浏览器下载某个部分中的所有文件 也许可以编写一个脚本来执行此操作 但
  • Recyclerview不调用onCreateViewHolder

    My RecyclerView不打电话onCreateViewHolder onBindViewHolder even MenuViewHolder构造函数 因此什么也没有出现在RecyclerView 我放了日志进行调试 没有显示任何日志
  • Bukkit 从库存中移除物品

    我正在尝试检查玩家的库存中是否有物品 如果有则删除其中一个 这是我现在所拥有的 Material ammomat parseMaterial plugin getConfig getString game ammo material Ite
  • Javascript - 请求的资源上不存在“Access-Control-Allow-Origin”标头

    我需要通过发送数据XmlHttpRequest从 JavaScript 到 Python 服务器 因为我使用的是本地主机 所以我需要使用CORS 我正在使用 Flask 框架及其模块flask cors 作为 JavaScript 我有这个
  • 配置 MPI 主机文件以使用多个用户身份

    我想在不同的机器上使用 mpirun 运行程序 所有带有 Open Mpi 1 5 的 linux 机器 现在我有可以登录的机器username A 以及我使用的另一组机器username B 所有机器都可以通过 ssh 访问 但我不知道如
  • sqlite删除非utf-8字符

    我有一个 sqlite 数据库 其中有一些疯狂的 ASCII 字符 我想删除它们 但我不知道如何去做 我用谷歌搜索了一些东西 发现有些人说将 REGEXP 与 mysql 一起使用 但这引发了一个错误 说 REGEXP 无法识别 这是我得到
  • 在css中未设置高度的情况下获取div的高度

    如果没有为我无法使用的元素设置 CSS 高度规则 有什么方法可以获取元素的高度 height jQuery 方法 因为它首先需要 CSS 规则集 还有其他方法可以获取高度吗 jQuery height将返回元素的高度 它不需要 CSS 定义
  • 为什么我不能在 python 中使用列表作为字典键?究竟什么可以使用,什么不能使用,为什么?

    我发现以下内容都是有效的 gt gt gt d gt gt gt d None foo gt gt gt d 1 3 baz 甚至模块也可以用作字典键 gt gt gt import sys gt gt gt d sys bar 但是 列表