字典简介
字典是一个键值对的集合。字典的键值可以是任何不可变(immutable)的数据类型,比如:字符串、数字、元组。字典的键值是无序互不相同的,就像是一个set,所以说字典的键值是set-like的。
元组作为键值时要注意,元组中的元素必须是不可变的数据类型,不能是列表等可变(mutable)的数据类型。
字典的初始化
- 大括号
tel = {'jack': 4098, 'sape': 4139}
- dict()
dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])
- 解析式
{x: x**2 for x in (2, 4, 6)}
- 针对字符串键值的特殊情况
dict(sape=4139, guido=4127, jack=4098)
字典的基本操作
>>> # dict的初始化
>>> tel = {'jack': 4098, 'sape': 4139}
>>> # 插入元素
>>> tel['guide'] = 4127
>>> tel
{'guide': 4127, 'jack': 4098, 'sape': 4139}
>>> # 提取元素
>>> tel['jack']
4098
>>> # 删除元素
>>> del tel['sape']
>>> tel['irv'] = 4127
>>> tel
{'guide': 4127, 'irv': 4127, 'jack': 4098}
>>> # 显示字典键值
>>> print(list(tel.keys()))
>>> # 显示字典键值并排序
>>> print(sorted(tel.keys()))
['jack', 'guide', 'irv']
['guide', 'irv', 'jack']
>>> # 判断键值是否包含于字典中
>>> print('guide' in tel)
>>> print('jack' not in tel)
True
False
字典的深入解析
在数据结构中,Map和Collection是两种并列的数据结构。dict就是Map类型的代表。Map类型中对键值的要求是hashable的。
官方文档:An object is hashable if has a hash value which never changes during its lifetime (ite needs a __hash__() method), and can be compared to other objects (it needs an __eq__() method).
hashable在Python中的解释,如果一个对象是hashable的,说明它有一个__hash__属性,这应该是该对象在哈希表中的位置,比如一个字符串的__hash__属性:
>>> a = 'c'
>>> a.__hash__
<method-wrapper '__hash__' of str object at 0x000001C3ACD9B228>
python中的列表不是hashable的,列表的hash属性,输出是空,即列表没有hash值,不是hashable的:
>>> l1 = [10, 1]
>>> l1.__hash__
同时,hashable的另一个必要条件是__eq__(),即可比较的。Python中的==就是调用的__eq__()。
官方文档: All of Python’s immutable built-in objects are hashable; mutable containers (such as lists or dictionaries) are not. 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中,所有的build-in对象都是hashable的,所有的可变容器(如list,dict)都不是hashable的。对象的哈希值由它们的id()决定。
PS:id()表示对象的存储位置。
hashable
hashable的两个条件:
-\ __hash__存在,即有哈希值
- __eq__()存在,即可比较
用户自己创建的类默认hashable,但是它们互不相等,它们的hash值来自于它们的id()
。看下面的例子:
>>> class object1():
>>> def __init__(self):
>>> self.a = 0
>>> # 类有hash值
>>> object1.__hash__
>>> # 类可比较,所以类是hashable
>>> object1 == object1
True
>>> object1.__hash__
<slot wrapper '__hash__' of 'object' objects>
>>> id(object1)
1939958360056
再来看它的实例:
>>> instance1 = object1()
>>> instance2 = object1()
>>> instance1 == instance2
>>> instance1.__hash__
<method-wrapper '__hash__' of object1 object at 0x000001C3AF584668>
>>> instance2.__hash__
<method-wrapper '__hash__' of object1 object at 0x000001C3AF584400>
>>> id(instance1)
1939972048488
>>> id(instance2)
1939972047872
可以看到,类是没有hash值的,但是有id()值,python中的任何变量(或者说是对象)都有id()值,id()值表示该变量在内存中的存储位置。但是类的两个实例是有hash值的,并且不相等,所以instance1 not is instance2, 自然instance1 != instance2
PS:is比较的是变量的存储位置,==变量值是否相等
Python中的相等
is
比较的是存储位置,即id()
的值==
比较的是值的大小,即使两个变量的存储位置不同,它们的值相同就是==的。
PS:有一点要注意,Python出于节约内存的目的,如果两个变量的值是相同的整形或者字符串,将使用同样的存储位置,所以:
>>> a = 2
>>> b = 2
>>> print(a is b, a == b)
True True
>>> id(a), id(b)
(1837933696, 1837933696)
字典中键值重复的情况
重复键值时,Python解释器自动选择最后一个。但是:
>>> D = {1: 'a', 1.0: 'b'}
>>> D
{1: 'b'}
字典中的键值要求是hashable,它们的比较方式是__eq__()也就是==,所以键值1和1.0是重合的。
字典的方法
>>> dir(D)
['__class__',
'__contains__',
...
'__subclasshook__',
'clear',
'copy',
'fromkeys',
'get',
'items',
'keys',
'pop',
'popitem',
'setdefault',
'update',
'values']
方法 |
---|
|
|
|
|
|
|
|
|
|
|
|
字典的迭代
三种方式:
>>> dishes = {'eggs': 2, 'sausage': 1, 'bacon': 1, 'spam': 500}
>>> for k in dishes.items():
>>> print(k)
('eggs', 2)
('sausage', 1)
('bacon', 1)
('spam', 500)
>>> for k in dishes:
>>> print(k)
eggs
sausage
bacon
spam
>>> for k in dishes.values():
>>> print(k)
2
1
1
500
- 深拷贝与浅拷贝:http://python.jobbole.com/82294/ ↩