字典以类似于下面的方式表示:
phonebook = {'Alice': '2341', 'Beth': '9102', 'Cecil': '3258'}
字典由键及其相应的值组成,这种键-值对称为项(item)。每个键与其值之间都用冒号 “:”
分隔,
项之间用逗号分隔,而整个字典放在花括号内。空字典“:”用两个花括号表示,类似于“{}”
。
注意:在字典(以及其他映射类型)中,键必须是独一无二的,而字典中的值无需如此。
items = [('name', 'Gumby'), ('age', 42)]
d = dict(items)
d
{'name': 'Gumby', 'age': 42}
d['name']
'Gumby'
还可使用关键字实参来调用这个函数,如下所示:
d = dict(name='Gumby', age=42)
d
{'name': 'Gumby', 'age': 42}
下面列出了创建电话簿数据库的代码示例:
- 一个简单的数据库,
- 一个将人名用作键的字典。每个人都用一个字典表示,
- 字典包含键'phone'和'addr',它们分别与电话号码和地址相关联。
people = {
'Alice': {
'phone': '2341',
'addr': 'Foo drive 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]))
phonebook
{'Alice': '2341', 'Beth': '9102', 'Cecil': '3258'}
"Cecil's phone number is {Cecil}.".format_map(phonebook)
"Cecil's phone number is 3258."
像这样使用字典时,可指定任意数量的转换说明符,条件是所有的字段名都是包含在字典中的键。 在模板系统中,这种字符串格式设置方式很有用(下面的示例使用的是HTML)。
template = '''<html>
<head><title>{title}</title></head>
<body>
<h1>{title}</h1>
<p>{text}</p>
... </body>'''
data = {'title': 'My Home Page', 'text': 'Welcome to my home page!'}
print(template.format_map(data))
<html> <head><title>My Home Page</title></head> <body> <h1>My Home Page</h1> <p>Welcome to my home page!</p> ... </body>
d = {}
d['name'] = 'Gumby'
d['age'] = 42
d
{'name': 'Gumby', 'age': 42}
returned_value = d.clear()
d
{}
print(returned_value)
None
这为何很有用呢?接下来看两个场景。下面是第一个场景:
x = {}
y = x
x['key'] = 'value'
y
{'key': 'value'}
x = {}
x = {}
y
{'key': 'value'}
下面是第二个场景:
x = {}
y = x
x['key'] = 'value'
y
{'key': 'value'}
x.clear()
y
{}
在这两个场景中, x 和 y 最初都指向同一个字典。在第一个场景中,
通过将一个空字典赋给 x 来“清空”它。这对 y 没有任何影响,它依然指向原来的字典。
这种行为可能正是自己想要的,
但要删除原来字典的所有元素,必须使用 clear
。如果这样做, y 也将是空的。
方法 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']}
当替换副本中的值时,原件不受影响。然而,如果修改副本中的值(就地修改而不是替换),
原件也将发生变化,因为原件指向的也是被修改的值(如这个示例中的 'machines'列表所示)。
为避免这种问题,一种办法是执行深复制,即同时复制值及其包含的所有值,等等。为此,
可使用模块 copy
中的函数 deepcopy
。
from copy import deepcopy
d = {}
d['names'] = ['Alfred', 'Bertrand']
c = d.copy()
dc = deepcopy(d)
d['names'].append('Clive')
c
{'names': ['Alfred', 'Bertrand', 'Clive']}
dc
{'names': ['Alfred', 'Bertrand']}
{}.fromkeys(['name', 'age'])
{'name': None, 'age': None}
这个示例首先创建了一个空字典,再对其调用方法 fromkeys
来创建另一个字典,这显得有点多余。
可以不这样做,而是直接对 dict
(前面说过, dict
是所有字典所属的类型)调用方法 fromkeys
。
dict.fromkeys(['name', 'age'])
{'name': None, 'age': None}
如果不想使用默认值 None
,可提供特定的值。
dict.fromkeys(['name', 'age'], '(unknown)')
{'name': '(unknown)', 'age': '(unknown)'}
d = {'x': 1, 'y': 2}
d.pop('x')
1
d
{'y': 2}
d = {'url': 'http://www.python.org', 'spam': 0, 'title': 'Python Web Site'}
d.popitem()
('title', 'Python Web Site')
d
{'url': 'http://www.python.org', 'spam': 0}
虽然 popitem
类似于列表方法 pop
,
但字典没有与 append
(它在列表末尾添加一个元素)对应的方法。
这是因为字典是无序的,类似的方法毫无意义。
d ={
'title': 'Python Web Site',
'url': 'http://www.python.org',
'changed': 'Mar 14 22:09:15 MET 2016'
}
x = {'title': 'Python Language Website'}
d.update(x)
d
{'title': 'Python Language Website', 'url': 'http://www.python.org', 'changed': 'Mar 14 22:09:15 MET 2016'}
对于通过参数提供的字典,将其项添加到当前字典中。如果当前字典包含键相同的项,就替换它。
可像调用本章前面讨论的函数 dict
(类型构造函数)那样调用方法 update
。这意味着调用 update
时,
可向它提供一个映射、一个由键-值对组成的序列(或其他可迭代对象)或关键字参数。