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

Posted IT界的测试混子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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值

以上是关于python的元组能作为字典的key吗?为什么?的主要内容,如果未能解决你的问题,请参考以下文章

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

Python 为啥list不能作为字典的key

Python字典到排序的元组,这可以做得更好吗?

Python字典,作为不增加值的元组键

04-字典集合,你真的了解吗

字典中的元组