python的元组能作为字典的key吗?为什么?

Q:python的元组能作为字典的key吗?为什么?

A:可以?不可以?

分析

其实这个问题,回答,可以或者不可以,都不够准确。追本溯源,我们来看看官网的说法。
Mapping Types — dict
https://docs.python.org/3/library/stdtypes.html#dict
hashbale
https://docs.python.org/3/glossary.html#term-hashable

然后,我们把问题拆解成以下几个小问题。

什么是dict(字典)?

A mapping object maps hashable values to arbitrary objects. Mappings are mutable objects. There is currently only one standard mapping type, the dictionary. (For other containers see the built-in list, set, and tuple classes, and the collections module.)

一个映射对象将可哈希值映射到任意对象。映射是可变的对象。目前只有一种标准的映射类型,即 dictionary。(关于其它的容器,请看内置的 list、set 和 tuple 类,以及 collections 模块)。

字典的键可以是什么?

A dictionary’s keys are almost arbitrary values. Values that are not hashable, that is, values containing lists, dictionaries or other mutable types (that are compared by value rather than by object identity) may not be used as keys. Numeric types used for keys obey the normal rules for numeric comparison: if two numbers compare equal (such as 1 and 1.0) then they can be used interchangeably to index the same dictionary entry. (Note however, that since computers store floating-point numbers as approximations it is usually unwise to use them as dictionary keys.)

一个 字典的键几乎是任意的值。不可散列的值,即包含列表字典其它可变类型的值(通过值而不是对象身份进行比较),不能用作键。用于键的数字类型遵守数字比较的正常规则:如果两个数字比较相等(如1和1.0),那么它们可以互换地用于索引同一个字典条目。(但是请注意,由于计算机将浮点数存储为近似值,因此用它们作为字典的键通常是不明智的。)


到这里应该就明确了:字典的值需是可散列的值


什么是hashable(可散列类型)?

An object is hashable if it has a hash value which never changes during its lifetime (it needs a hash() method), and can be compared to other objects (it needs an eq() method). Hashable objects which compare equal must have the same hash value.

一个对象是可散列的,如果它有一个在其生命周期内永不改变的散列值 (它需要一个 hash() 方法),并且可以与其他对象比较 (它需要一个 eq() 方法)。比较相等的可散列对象必须有相同的散列值。

Hashability makes an object usable as a dictionary key and a set member, because these data structures use the hash value internally.

哈希性使得一个对象可以作为字典的键和集合成员使用,因为这些数据结构在内部使用哈希值。

Most of Python’s immutable built-in objects are hashable; mutable containers (such as lists or dictionaries) are not; immutable containers (such as tuples and frozensets) are only hashable if their elements are hashable. Objects which are instances of user-defined classes are hashable by default. They all compare unequal (except with themselves), and their hash value is derived from their id().

大多数 Python 的不可变的内置对象是可散列的;可变的容器 (如列表或字典) 不是;不可变的容器 (如元组和 frozensets) 只有在其元素是可散列的情况下才是可散列的。作为用户定义的类的实例的对象默认是可哈希的。它们都是不等价的(除了与自己的比较),它们的哈希值来自于它们的id()。


翻译完官网的东西,总结一下:
可变的容器 (如列表或字典) 不是可散列的;不可变的容器 (如元组和 frozensets) 只有在其元素是可散列的情况下才是可散列的。


举个栗子

元组的元素都是不可变类型

d = {}
t1 = (1,'a',(2,3))
d[t1] = "test1"

在这里插入图片描述

元组的元素包含list

d={}
t2 = (1,'a',(2,3),[1,2,3])
d[t2] = "test2"

在这里插入图片描述

元组的元素包含dict

d={}
t3 = (1,'a',(2,3),{})
d[t3] = "test3"

在这里插入图片描述

结论

元组只有在其元素是可散列的(不可变类型)情况下,才可以作为字典的key值

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值