列表和字典的区别是列表可以通过索引来访问值,而字典可以通过名称来访问各个值。
字典这种数据结构称为映射(mapping),字典是Python中唯一内置映射类型,值不按照顺序排列,而是存储再键下面。
其中键可以是数字、字符串或元组等不可变数据类型。
字典的用途
字典的名称指出了这种数据结构的用途。日常生活中的字典和Python中的字典都能够轻松的通过单词(键)获取其定义的值。
- 表示棋盘的分布,其中每个键都是由坐标组成的元组
- 存储文件修改时间,其中的键为文件名
- 数字电话/地址簿
通过列表查找数据:
>>>
>>> names = [\'Alice\', \'Beth\', \'Cecil\', \'Dee-Dee\', \'Earl\']
>>> numbers = [\'2341\', \'9102\', \'3158\', \'0142\', \'5551\']
>>> numbers[names.index(\'Cecil\')] # 要查找Ceil的号码,通过列表的方式很麻烦
\'3158\'
>>>
创建和使用字典
上面查找电话号码的,可以通过创建一个字典实现。
>>> phonebook = {\'Alice\': \'2314\', \'Beth\': \'9102\', \'Cecil\': \'3258\'}
>>> phonebook[\'Alice\']
\'2314\'
>>>
字典(dict)由键(key)及其对应的值(value)组成,这种键-值对称为项(item)。
在上面的示例中,键为名字,值为手机号。
每个键与值之间都是用冒号(:)分隔,项之间使用逗号分隔,整个字典放在大括号中。
空字典(没有任何项)用两个大括号表示,类似于 {}
。
在字典(以及其他映射类型)中,键必须是独一无二的,而字典中的值无此要求。
可以使用函数dict从其他映射(如其他字典)或键值对序列创建字典:
>>>
>>> items = [(\'name\', \'Gubmy\'), (\'age\', 42)]
>>> d = dict(items)
>>> d
{\'name\': \'Gubmy\', \'age\': 42}
>>> d[\'name\']
\'Gubmy\'
>>>
>>>
>>> d = dict(name=\'Gumby\', age=42) # 使用关键字实参创建字典
>>> d
{\'name\': \'Gumby\', \'age\': 42}
>>>
字典基本操作
字典的基本行为在很多方面类似于序列。
len(d)
返回字典项(键值对)数d[k]
返回与k
相关联的值d[k] = v
将值v
关联到键k
del d[k]
删除键为k
的项k in d
检查字典d
是否包含键位k
的项
字典和列表有一些不同之处。
-
键的类型:字典中键可以是整数,单并非必须是整数。字典中的键可以是任何不可变的类型,如浮点数(实数)、字符串、元组。——字典的主要优点
-
自动添加:即便是字典中原本没有键,也可以给他赋值,这将在字典中创建一个新项;但是如果不适用append或其他类似方法,就不能给列表中没有的元素赋值
-
成员资格:表达式
k in d
(其中d
是一个字典)查找的是键而不是值,而表达式v in l
(其中l
是一个列表)查找的是值而不是索引。其实字典中的键可以理解为列表中的索引,所以这里不一样。查字典中是否包含键的效率比检查列表中是否包含值更高,这也说明了数据结构越大效率差距就越大。>>> >>> x = [] >>> x[42] = \'Foobar\' # 因为空列表中没有索引42,所以会报错。定义的时候必须使用[None]*43才可以 Traceback (most recent call last): File \"<stdin>\", line 1, in <module> IndexError: list assignment index out of range >>> >>> x = {} >>> x[42] = \'Foobar\' # 空字典中可以给没有的键赋值,会生成新的item >>> x {42: \'Foobar\'} >>>
创建电话簿数据库代码示例
# 一个简单的数据库
# 将一个人名用作键的字典,每个人都用一个字典表示
# 字典中包含键\'phone\'和\'addr\',它们分别与电话号码和地址相关联
people = {
\'Alice\': {
\'phone\': \'2341\',
\'addr\': \'Foo driver 23\'
},
\'Beth\': {
\'phone\': \'9102\',
\'addr\': \'Bar street 42\'
},
\'Cecil\': {
\'phone\': \'3158\',
\'addr\': \'Baz avenue 90\'
}
}
# 电话号码和地址的描述性标签,供打印输出时使用
labels = {
\'phone\': \'phone number\',
\'addr\': \'address\'
}
name = input(\'Name: \')
# 要查找电话号码还是地址
request = input(\'Phone number (p) or address (a) ? \')
# 使用正确的键
if request == \'p\':
key = \'phone\'
if request == \'a\': key = \'addr\'
# 仅当名字是字典中包含的键时才打印信息
if name in people:
print(\"{}\'s {} is {}.\".format(name, labels[key], people[name][key]))
# Output
Name: Beth
Phone number (p) or address (a) ? p
Beth\'s phone number is 9102.
格式化引用字典
字符产格式化引用最常用的方法为format
。
同样可以通过在字典中存储一系列命名的值,可让格式设置更容易些。提取的时候只需在格式字符串中提取所需要的信息即可,使用format_map
来指出你将通过一个映射来提供所需要的信息。
>>
>>> phonebook = {\'Alice\': \'2314\', \'Beth\': \'9102\', \'Cecil\': \'3258\'}
>>> \"Cecil\'s phone number is {Cecil}.\".format_map(phonebook)
\"Cecil\'s phone number is 3258.\"
>>>
>>>
>>> # 只要所有的字段名称都包含在字典的键中,可以指定任意数量的转换说明符。如下:
template = \'\'\'
<html>
<head>
<title>
{title}
</title>
</head>
<body>
<h1>
{title}
</h1>
<p>
{text}
</p>
</body>
</html>
\'\'\'
data = {\'title\': \'My Home Page\', \'text\': \'Welcome to my home page!\'}
print(template.format_map(data))
# Output
\'\'\'
<html>
<head>
<title>
My Home Page
</title>
</head>
<body>
<h1>
My Home Page
</h1>
<p>
Welcome to my home page!
</p>
</body>
</html>
\'\'\'
字典方法
与其他内置类型一样,字典也有方法,字典的方法很有用,介绍几个常用的字典方法。
- clear
方法clear删除所有字典项。
>>>
>>> d = {}
>>> d[\'name\'] = \'Gumby\'
>>> d[\'age\'] = 42
>>> d
{\'name\': \'Gumby\', \'age\': 42}
>>> returned_value = d.clear()
>>> d
{}
>>> print(returned_value)
None
>>>
>>> # 场景一:通过给x赋值空字典来“清空”x,但是不影响y。这种方法很有用。
>>> x = {}
>>> y = x
>>> x[\'key\'] = \'value\'
>>> y
{\'key\': \'value\'}
>>> x
{\'key\': \'value\'}
>>> x = {}
>>> y
{\'key\': \'value\'}
>>> x
{}
>>>
>>> # 场景二:调用clear方法,会同时删除x、y中的元素。这种方法很有用
>>> x = {}
>>> y = x
>>> x[\'key\'] = \'value\'
>>> y
{\'key\': \'value\'}
>>> x
{\'key\': \'value\'}
>>> x.clear()
>>> y
{}
>>> x
{}
>>>
- copy
方法copy返回一个新字典,其包含的键值对与原来的字典相同(这个方法执行的是浅复制,因为值本身是原件,而非副本)。
浅复制得到的副本,替换副本中的值,原件不受影响,但是修改副本中的值也会一并修改原件中的值,因为原件指向的也是被修改的值。
深复制就可以避免这种问题。
>>>
>>> x = {\'username\': \'admin\', \'machines\': [\'foo\', \'bar\', \'baz\']}
>>> y = x.copy() # 浅复制
>>> y[\'username\'] = \'mlh\'
>>> y[\'machines\'].remove(\'bar\')
>>> y
{\'username\': \'mlh\', \'machines\': [\'foo\', \'baz\']}
>>> x
{\'username\': \'admin\', \'machines\': [\'foo\', \'baz\']} # 原件变化
>>>
>>>
>>>
>>> from copy import deepcopy
>>> d = {}
>>> d[\'name\'] = [\'Alfred\', \'Berthand\']
>>> c = d.copy()
>>> dc = deepcopy(d) # 深复制
>>> d[\'name\'].append(\'Clive\')
>>> c
{\'name\': [\'Alfred\', \'Berthand\', \'Clive\']} # 原件不变
>>> dc
{\'name\': [\'Alfred\', \'Berthand\']}
>>>
- fromkeys
方法fromkeys创建一个新字典,其中包含指定的键,且每个键对应的值都是None。
# 从空字典创建另一个字典
d = {}
df = d.fromkeys([\'name\', \'age\'])
print(df) # {\'name\': None, \'age\': None}
# 直接使用dict创建字典(dict是所有字典所属类型)
df = dict.fromkeys([\'name\', \'key\'])
print(df) # {\'name\': None, \'age\': None}
# 提供特定的值创建字典
df1 = dict.fromkeys([\'name\', \'age\'], \'(unknown)\')
print(df1) # {\'name\': \'(unknown)\', \'age\': \'(unknown)\'}
- get
方法get为访问字典项提供了宽松的环境。因为通常访问字典中没有的项,将发生错误。
>>>
>>> d = {}
>>> d[\'name\'] # 通常访问报错
Traceback (most recent call last):
File \"<stdin>\", line 1, in <module>
KeyError: \'name\'
>>>
>>> print(d.get(\'name\')) # 通过get方法访问返回None
None
>>>
>>> d.get(\'name\', \'N/A\') # 指定默认值(如果有值就返回,没有就返回默认值)
\'N/A\'
>>>
>>> d[\'name\'] = \'Eric\'
>>> d
{\'name\': \'Eric\'}
>>> d.get(\'name\') # 访问的时候有值
\'Eric\'
使用get方法优化有的代码:
# 一个使用get()的简单的数据库,可以保证即使输入的值不对也能正常输出
# 将一个人名用作键的字典,每个人都用一个字典表示
# 字典中包含键\'phone\'和\'addr\',它们分别与电话号码和地址相关联
people = {
\'Alice\': {
\'phone\': \'2341\',
\'addr\': \'Foo driver 23\'
},
\'Beth\': {
\'phone\': \'9102\',
\'addr\': \'Bar street 42\'
},
\'Cecil\': {
\'phone\': \'3158\',
\'addr\': \'Baz avenue 90\'
}
}
# 电话号码和地址的描述性标签,供打印输出时使用
labels = {
\'phone\': \'phone number\',
\'addr\': \'address\'
}
name = input(\'Name: \')
# 要查找电话号码还是地址
request = input(\'Phone number (p) or address (a)? \')
# 使用正确的键
key = request # 如果request既不是\'p\'也不是\'a\'
if request == \'p\': key = \'phone\'
if request == \'a\': key = \'addr\'
# 使用get提供默认值
person = people.get(name, {})
label = labels.get(key, key)
result = person.get(key, \'not available\')
# 才打印信息
print(\"{}\'s {} is {}.\".format(name, label, result))
- items
方法items返回一个包含所有字典项的列表,其中每个元素都已(key, value)的形式展示。其中排序是不确定的。
返回值属于一种名称为字典视图的特殊类型,可迭代,可检查长度。字典视图生成后不会复制原字典,即使修改了原字典。
可以使用list将字典视图转换为列表。
>>>
>>> d = {\'title\': \'Python Web Site\', \'url\': \'http://www.python.org\', \'span\': 0}
>>> d.items()
dict_items([(\'title\', \'Python Web Site\'), (\'url\', \'http://www.python.org\'), (\'span\', 0)]) # 返回值属于一种名称为字典视图的特殊类型,可迭代,可检查长度
>>>
>>> it = d.items()
>>> len(it)
3
>>> (\'span\', 0) in it
True
>>>
>>> d[\'span\'] = 1 # 修改字典d并不影响字典视图it
>>> (\'span\', 0) in it
False
>>> d[\'span\'] = 0
>>> (\'span\', 0) in it
True
>>>
>>> l = list(d.items()) # 使用list方法将字典视图转换为列表
>>> l
[(\'title\', \'Python Web Site\'), (\'url\', \'http://www.python.org\'), (\'span\', 0)]
>>>
- keys
方法keys返回一个字典视图,其中包含指定字典中的键。
>>>
>>> d = {\'title\': \'Python Web Site\', \'url\': \'http://www.python.org\', \'span\': 0}
>>> d.keys()
dict_keys([\'title\', \'url\', \'span\'])
>>>
- values
方法values返回一个由字典中的值组成的字典视图。不同于方法keys,方法values返回的视图可能包含重复的值。
>>>
>>> d = {}
>>> d[1] = 1
>>> d[2] = 2
>>> d[3] = 3
>>> d[4] = 1
>>> d
{1: 1, 2: 2, 3: 3, 4: 1}
>>> d.values()
dict_values([1, 2, 3, 1])
>>>
- pop
方法pop可用于获取与指定键关联的的值,并将该键值对从字典中删除。
>>>
>>> d = {\'x\': 1, \'y\': 2, \'z\': 3}
>>> d.pop(\'x\')
1
>>> d
{\'y\': 2, \'z\': 3}
>>>
- popitem
方法popitem类似于list.pop,但list.pop弹出列表的最后一个元素,而popitem随机弹出一个字典项(因为字典项的顺序是不确定的,所有没有\'最后一个元素\'的概念),因此字典也没有类似列表中append的方法,无意义。
这个方法可以高效的逐个删除并处理所有字典项,因为这样无需先获取字典列表。
>>>
>>> d = {\'title\': \'Python Web Site\', \'url\': \'http://www.python.org\', \'span\': 0}
>>> d.popitem()
(\'span\', 0)
>>> d
{\'title\': \'Python Web Site\', \'url\': \'http://www.python.org\'}
>>>
- setdefault
方法setdefault有点像get,有键时获取值,但是无键时可以添加键值对
>>>
>>> d = {\'title\': \'Python Web Site\', \'url\': \'http://www.python.org\', \'span\': 0}
>>> d.setdefault(\'title\')
\'Python Web Site\'
>>> d
{\'title\': \'Python Web Site\', \'url\': \'http://www.python.org\', \'span\': 0}
>>> d.setdefault(\'name\', \'N/A\') # setdefault指定的值不存在时,返回指定值并更新字典;如果没有指定,同get一样返回None
\'N/A\'
>>> d
{\'title\': \'Python Web Site\', \'url\': \'http://www.python.org\', \'span\': 0, \'name\': \'N/A\'}
>>> d.setdefault(\'type\', \'Python\')
\'Python\'
>>> d
{\'title\': \'Python Web Site\', \'url\': \'http://www.python.org\', \'span\': 0, \'name\': \'N/A\', \'type\': \'Python\'}
>>>
- update
方法update使用一个字典中的项来更新另一个字典,如果没有就添加,如果有就更新。
>>>
>>> d = {\'title\': \'Python Web Site\', \'url\': \'http://www.python.org\', \'spam\': 0}
>>> x = {\'title\': \'Python Language Website\'}
>>> d.update(x) # 这里要理解下,是对字典d调用update方法,所以因该是使用字典x去更新字典d的内容,而不是改变字典x的内容
>>> d
{\'title\': \'Python Language Website\', \'url\': \'http://www.python.org\', \'spam\': 0}
>>>
来源:https://www.cnblogs.com/palien/p/16912102.html
本站部分图文来源于网络,如有侵权请联系删除。