Files
ailearning/docs/da/016.md
2020-10-19 21:08:55 +08:00

644 lines
9.2 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 字典
字典 `dictionary` ,在一些编程语言中也称为 `hash` `map` ,是一种由键值对组成的数据结构。
顾名思义,我们把键想象成字典中的单词,值想象成词对应的定义,那么——
一个词可以对应一个或者多个定义,但是这些定义只能通过这个词来进行查询。
## 基本操作
### 空字典
**Python** 使用 `{}` 或者 `dict()` 来创建一个空的字典:
In [1]:
```py
a = {}
type(a)
```
Out[1]:
```py
dict
```
In [2]:
```py
a = dict()
type(a)
```
Out[2]:
```py
dict
```
有了dict之后可以用索引键值的方法向其中添加元素也可以通过索引来查看元素的值
### 插入键值
In [3]:
```py
a["one"] = "this is number 1"
a["two"] = "this is number 2"
a
```
Out[3]:
```py
{'one': 'this is number 1', 'two': 'this is number 2'}
```
### 查看键值
In [4]:
```py
a['one']
```
Out[4]:
```py
'this is number 1'
```
### 更新键值
In [5]:
```py
a["one"] = "this is number 1, too"
a
```
Out[5]:
```py
{'one': 'this is number 1, too', 'two': 'this is number 2'}
```
### 初始化字典
可以看到Python使用`key: value`这样的结构来表示字典中的元素结构,事实上,可以直接使用这样的结构来初始化一个字典:
In [6]:
```py
b = {'one': 'this is number 1', 'two': 'this is number 2'}
b['one']
```
Out[6]:
```py
'this is number 1'
```
### 字典没有顺序
当我们 `print` 一个字典时,**Python**并不一定按照插入键值的先后顺序进行显示,因为字典中的键本身不一定是有序的。
In [7]:
```py
print a
```
```py
{'two': 'this is number 2', 'one': 'this is number 1, too'}
```
In [8]:
```py
print b
```
```py
{'two': 'this is number 2', 'one': 'this is number 1'}
```
因此,**Python**中不能用支持用数字索引按顺序查看字典中的值,而且数字本身也有可能成为键值,这样会引起混淆:
In [9]:
```py
# 会报错
a[0]
```
```py
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-9-cc39af2a359c> in <module>()
1 # 会报错
----> 2 a[0]
KeyError: 0
```
### 键必须是不可变的类型
出于hash的目的Python中要求这些键值对的**键**必须是**不可变**的而值可以是任意的Python对象。
一个表示近义词的字典:
In [10]:
```py
synonyms = {}
synonyms['mutable'] = ['changeable', 'variable', 'varying', 'fluctuating',
'shifting', 'inconsistent', 'unpredictable', 'inconstant',
'fickle', 'uneven', 'unstable', 'protean']
synonyms['immutable'] = ['fixed', 'set', 'rigid', 'inflexible',
'permanent', 'established', 'carved in stone']
synonyms
```
Out[10]:
```py
{'immutable': ['fixed',
'set',
'rigid',
'inflexible',
'permanent',
'established',
'carved in stone'],
'mutable': ['changeable',
'variable',
'varying',
'fluctuating',
'shifting',
'inconsistent',
'unpredictable',
'inconstant',
'fickle',
'uneven',
'unstable',
'protean']}
```
另一个例子:
In [11]:
```py
# 定义四个字典
e1 = {'mag': 0.05, 'width': 20}
e2 = {'mag': 0.04, 'width': 25}
e3 = {'mag': 0.05, 'width': 80}
e4 = {'mag': 0.03, 'width': 30}
# 以字典作为值传入新的字典
events = {500: e1, 760: e2, 3001: e3, 4180: e4}
events
```
Out[11]:
```py
{500: {'mag': 0.05, 'width': 20},
760: {'mag': 0.04, 'width': 25},
3001: {'mag': 0.05, 'width': 80},
4180: {'mag': 0.03, 'width': 30}}
```
键(或者值)的数据类型可以不同:
In [13]:
```py
people = [
{'first': 'Sam', 'last': 'Malone', 'name': 35},
{'first': 'Woody', 'last': 'Boyd', 'name': 21},
{'first': 'Norm', 'last': 'Peterson', 'name': 34},
{'first': 'Diane', 'last': 'Chambers', 'name': 33}
]
people
```
Out[13]:
```py
[{'first': 'Sam', 'last': 'Malone', 'name': 35},
{'first': 'Woody', 'last': 'Boyd', 'name': 21},
{'first': 'Norm', 'last': 'Peterson', 'name': 34},
{'first': 'Diane', 'last': 'Chambers', 'name': 33}]
```
### 使用 dict 初始化字典
除了通常的定义方式,还可以通过 `dict()` 转化来生成字典:
In [14]:
```py
inventory = dict(
[('foozelator', 123),
('frombicator', 18),
('spatzleblock', 34),
('snitzelhogen', 23)
])
inventory
```
Out[14]:
```py
{'foozelator': 123, 'frombicator': 18, 'snitzelhogen': 23, 'spatzleblock': 34}
```
利用索引直接更新键值对:
In [15]:
```py
inventory['frombicator'] += 1
inventory
```
Out[15]:
```py
{'foozelator': 123, 'frombicator': 19, 'snitzelhogen': 23, 'spatzleblock': 34}
```
## 适合做键的类型
在不可变类型中,整数和字符串是字典中最常用的类型;而浮点数通常不推荐用来做键,原因如下:
In [16]:
```py
data = {}
data[1.1 + 2.2] = 6.6
# 会报错
data[3.3]
```
```py
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-16-a48e87d01daa> in <module>()
2 data[1.1 + 2.2] = 6.6
3 # 会报错
----> 4 data[3.3]
KeyError: 3.3
```
事实上,观察`data`的值就会发现,这个错误是由浮点数的精度问题所引起的:
In [17]:
```py
data
```
Out[17]:
```py
{3.3000000000000003: 6.6}
```
有时候,也可以使用元组作为键值,例如,可以用元组做键来表示从第一个城市飞往第二个城市航班数的多少:
In [19]:
```py
connections = {}
connections[('New York', 'Seattle')] = 100
connections[('Austin', 'New York')] = 200
connections[('New York', 'Austin')] = 400
```
元组是有序的,因此 `('New York', 'Austin')``('Austin', 'New York')` 是两个不同的键:
In [20]:
```py
print connections[('Austin', 'New York')]
print connections[('New York', 'Austin')]
```
```py
200
400
```
## 字典方法
### `get` 方法
之前已经见过用索引可以找到一个键对应的值但是当字典中没有这个键的时候Python会报错这时候可以使用字典的 `get` 方法来处理这种情况,其用法如下:
```py
`d.get(key, default = None)`
```
返回字典中键 `key` 对应的值,如果没有这个键,返回 `default` 指定的值(默认是 `None` )。
In [21]:
```py
a = {}
a["one"] = "this is number 1"
a["two"] = "this is number 2"
```
索引不存在的键值会报错:
In [22]:
```py
a["three"]
```
```py
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-22-8a5f2913f00e> in <module>()
----> 1 a["three"]
KeyError: 'three'
```
改用get方法
In [24]:
```py
print a.get("three")
```
```py
None
```
指定默认值参数:
In [25]:
```py
a.get("three", "undefined")
```
Out[25]:
```py
'undefined'
```
### `pop` 方法删除元素
`pop` 方法可以用来弹出字典中某个键对应的值,同时也可以指定默认参数:
```py
`d.pop(key, default = None)`
```
删除并返回字典中键 `key` 对应的值,如果没有这个键,返回 `default` 指定的值(默认是 `None` )。
In [26]:
```py
a
```
Out[26]:
```py
{'one': 'this is number 1', 'two': 'this is number 2'}
```
弹出并返回值:
In [27]:
```py
a.pop("two")
```
Out[27]:
```py
'this is number 2'
```
In [28]:
```py
a
```
Out[28]:
```py
{'one': 'this is number 1'}
```
弹出不存在的键值:
In [29]:
```py
a.pop("two", 'not exist')
```
Out[29]:
```py
'not exist'
```
与列表一样,`del` 函数可以用来删除字典中特定的键值对,例如:
In [30]:
```py
del a["one"]
a
```
Out[30]:
```py
{}
```
### `update`方法更新字典
之前已经知道,可以通过索引来插入、修改单个键值对,但是如果想对多个键值对进行操作,这种方法就显得比较麻烦,好在有 `update` 方法:
```py
`d.update(newd)`
```
将字典`newd`中的内容更新到`d`中去。
In [31]:
```py
person = {}
person['first'] = "Jmes"
person['last'] = "Maxwell"
person['born'] = 1831
print person
```
```py
{'born': 1831, 'last': 'Maxwell', 'first': 'Jmes'}
```
把'first'改成'James',同时插入'middle'的值'Clerk'
In [32]:
```py
person_modifications = {'first': 'James', 'middle': 'Clerk'}
person.update(person_modifications)
print person
```
```py
{'middle': 'Clerk', 'born': 1831, 'last': 'Maxwell', 'first': 'James'}
```
### `in`查询字典中是否有该键
In [33]:
```py
barn = {'cows': 1, 'dogs': 5, 'cats': 3}
```
`in` 可以用来判断字典中是否有某个特定的键:
In [35]:
```py
'chickens' in barn
```
Out[35]:
```py
False
```
In [34]:
```py
'cows' in barn
```
Out[34]:
```py
True
```
### `keys` 方法,`values` 方法和`items` 方法
```py
`d.keys()`
```
返回一个由所有键组成的列表;
```py
`d.values()`
```
返回一个由所有值组成的列表;
```py
`d.items()`
```
返回一个由所有键值对元组组成的列表;
In [36]:
```py
barn.keys()
```
Out[36]:
```py
['cows', 'cats', 'dogs']
```
In [37]:
```py
barn.values()
```
Out[37]:
```py
[1, 3, 5]
```
In [38]:
```py
barn.items()
```
Out[38]:
```py
[('cows', 1), ('cats', 3), ('dogs', 5)]
```