字典是python中唯一内建的映射类型。字典中的值并没有特殊的顺序,但是都存储在一个特定的键(key)里。键可以是数字、字符窜甚至是元组。
为什么需要字典
>>>names = ['Alice', 'Betch', 'Cecil', 'Dee-Dee', 'Earl']
>>>numbers = ['2341', '9102', '3158', '0142', '5551']
>>>numbers[names.index('Cecil')] 3158 ##创建和使用字典
字典可以通过下面的方式创建:
>>>phonebook = {'Alice': '2341', 'Beth': '9012', 'Cecil': '3258'}
每个键和它的值之间用冒号(:)隔开,项之间用逗号(,)隔开,而整个字典由一对大括号括起来
[注: 字典中的键是唯一的,而值并不唯一]
可以用dict函数,通过其他映射或(键, 值)这样的序列对建立字典
>>>items = [('name', 'Gumby'), ('age', '42')]
>>>d = dict(items) >>>d {'age': 42, 'name': 'Gumby'}
>>>d['name'] 'Gumby'
如果不带任何参数,则dict函数返回一个新的空字典
字典的基本行为在很多方面与序列类似:
[注: 在字典中查找键的成员资格比在列表中检查值的成员资格更有效,数据结构的规模越大,两者的效率差距越明显]
示例4-1
# 简单数据库
# 使用人名作为键的字典。每个人用另一个字典来表示,其见为'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 = raw_input('Name: ')
# 查找电话号码还是地址? 使用正确的键
request = raw_input('Key (p or a): ')
# 使用正确的键:
if request == 'p': key = 'phone'
if request == 'a': key = 'addr'
# 如果名字是字典中有效键才打印信息:
if name in people: print "%s's %s is %s." % \
(name, label[key], people[name][key])
$./4-1.py
Name: Beth
Key (p or a): p
Beth's phone number is 9102.
在每个转换说明符中的%字符后面,可以加上(用圆括号括起来)键,后面再跟上其他的说明符
>>>phonebook = {'Beth': '9102', 'Alice': '2314', 'Cecil': '3258'}
>>>"Cecil's phone number is $(Cecil)s." % phonebook
"Cecil's phone number is 3258."
这类字符串格式化在模板系统中非常有用(例如HTML):
>>>template = '''<html>
<head><title>%(title)s</title></head>
<body>
<h1>%(title)s</h1>
<p>%(text)s</p>
</body>
</html>'''
>>>data = {'title': 'My Home Page', 'text': 'Welcom to my home page!'}
>>>print template % data
<html>
<head><title>My Home Page</title></head>
<body>
<h1>My Home Page</h1>
<p>Welcom to my home page</p>
</body>
</html>
clear
clear方法清除字典中所有项。这个操作无返回值(或说返回None)
>>>d = {}
>>>d['name'] = 'Gumby'
>>>d['age'] = '42'
>>>d
{'age': '42', 'name': 'Gumby'}
>>>return_value = d.clear()
>>>d
{}
>>>print return_value
None
为什么需要clear
>>>x = {}
>>>y = x
>>>x['key'] = 'value'
>>>y
{'key': 'value'}
>>>x = {}
>>>y
{'key': 'value'}
>>>x = {}
>>>y = x
>>>x['key'] = 'value'
>>>y
{'key': 'value'}
>>>x.clear()
>>>y
{}
两种情况中,x和y最初对应同一个字典。情况一中,通过将x关联到一个新的空字典来"清空"它,对y一点影响也没有,它还是关联到原先的字典。这可能是所需要的行为,但是如果真的想清空原始字典中所有的元素,必须使用clear方法。
copy
copy方法返回一个具有相同键-值对的新字典
>>>x = {'username': 'admin', 'machines': ['foo', 'bar', 'bza']}
>>>y = x.copy()
>>>y['username'] = 'mlh'
>>>y['machines'].remove('bar')
>>>y
{'username': 'mlh', 'machines': ['foo', 'baz']}
>>>x
{'username': 'admin', 'machines': ['foo', 'baz']}
copy实现的是浅复制,当在副本中替换指的时候,原始字典不受影响,但是,如果修改了某个值(原地修改,而非替换),原始的字典也会改变,应为同样的值也存储在原字典中。*为避免上述问题,可使用深复制,复制其包含所有的值。可以使用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
fromkeys方法使用给定的键建立新的字典,每个键默认对应的值为None。
>>>{}.fromkeys(['name', 'age'])
{'age': None, 'name': None}
可以直接在所有字典的类型dict上面调用方法:
>>>dict.fromkeys(['name', 'age')
{'age': None, 'name': None}
如果不想使用None作为默认值,也可以自己提供默认值
>>>dict.fromkeys(['name', 'age'], '(unknown)')
{'age': '(unknown)', 'name': '(unknown)'}
get
get方法是个更宽松的访问字典项的方法。一般来说,如果试图访问字典中不存在的项会出错
>>>d = {}
>>>print d['name']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'name'
>>>print d.get('name')
None
当使用get访问一个不存在的键时,没有任何异常,而得到了None值。还可以定义"默认"值,替换None:
>>>d = {}
>>>d.get('name', 'N/A')
'N/A'
如果键存在,get用起来就像普通的字典查询一样:
>>>d = {}
>>>d['name'] = 'Eric'
>>>d.get('name')
'Eric'
很好奇两件事,再次做验证:
>>>d['name'] = 'Eric'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'd' is not defined
由上述知,变量需先定义再使用。
>>>d = {}
>>>d['name'] = 'Eric'
>>>d.get('name', 'N/A')
'Eric'
由上述知,当使用get访问一个键时,并且自定义"默认"值,如果键存在,则值为键对应的值,否则,值为None。
示例4-2
# 使用get()的简单数据库
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 = raw_input('Name: ')
request = raw_input('Phone number (p) or address (a)? ')
key = request
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's %s is %s." % (name, label, result)
$./4-2.py
Name: Alice
phone number (p) or address(a)? p
Alice's phone number is 2341.
has_key
has_key方法可以检查字典中是否含有给出的键。表达式d.has_key(k)相当于表达式k in d
>>>d = {}
>>>d.has_key('name')
False
>>>d['name'] = 'Eric'
>>>d.has_key('name')
True
items和iteritems
items方法将所有的字典项以列表方式返回,这些列表项中的每一项都来自于(键, 值)。但是项在返回时并没有特殊顺序。
>>>d = {'title': 'Python Web Site', 'url': 'http://www.python.org', 'spam': 0}
>>>d.items()
[('url': 'http://www.python.org', ('spam', 0), ('title', 'Python Web
Site')]
iteritems方法的作用大致相同,但是会返回一个迭代器对象而不是列表:
>>>d = {'title': 'Python Web Site', 'url': 'http://www.python.org', 'spam': 0}
>>>it = d.iteritems()
>>>it
<dictionary-iterator object at 169050>
>>>list(it) # Convert the iterator to a list
[('url': 'http://www.python.org', ('spam', 0), ('title', 'Python Web
Site')]
keys和iterkeys
keys方法将字典中的以列表形式返回,而iterkeys则返回针对键的迭代器
>>> d = {'title': 'Python Web Site', 'url': 'http://www.python.org', 'spam': 0}
>>> d.keys()
['url', 'spam', 'title']
>>> it = d.iterkeys()
>>> it
<dictionary-keyiterator object at 0x9b9bc5c>
>>> list(it)
['url', 'spam', 'title']
pop
pop方法用来获得对应于给定键的值,然后每个键-值对从字典中移除
>>> d = {'x': 1, 'y': 2}
>>> d.pop('x')
1
>>> d
{'y': 2}
popitem
popitem方法类似于list.pop,后者会弹出列表的最后一个元素。但不同的是,popitem弹出随机的项,因为字典并没有"最后的元素"或其他有关顺序的概念。
>>> d = {'title': 'Python', 'url': 'http://www.python.org', 'spam': 0}
>>> d
{'url': 'http://www.python.org', 'spam': 0, 'title': 'Python'}
>>> d.popitem()
('url', 'http://www.python.org')
>>> d.popitem()
('spam', 0)
>>> d.popitem()
('title', 'Python')
>>> d
{}
setdefault
setdefault方法在某种程度上类似于get方法,就是能够获得与给定键相关联的值,除此之外,setdefault还能在字典中不含有给给定键的情况下设定相应的键值。
>>> d = {}
>>> d.setdefault('name', 'N/A')
'N/A'
>>> d
{'name': 'N/A'}
>>> d['name'] = 'Gumby'
>>> d.setdefault('name', 'N/A')
'Gumby'
>>> d
{'name': 'Gumby'}
当键不存在的时候,setdefault返回默认值并且相应的更新字典。如果键存在,那么就返回与其对应的值,但不改变字典。
>>> d = {}
>>> print d.setdefault('name')
None
>>> d
{'name': None}
update
update方法可以利用一个字典项更新另一个字典
>>> d = {'title': 'Python Web Site', 'url': 'http://www.python.org', 'change': 'Mar 14 22:09:15 MET 2008'}
>>> x = {'title': 'Python Language Website'}
>>> d.update(x)
>>> d
{'url': 'http://www.python.org', 'change': 'Mar 14 22:09:15 MET 2008', 'title': 'Python Language Website'}
提供的字典中的项会被添加到旧的字典中,若有相同的键则会进行覆盖。
values和itervalues
values方法以列表的形式返回字典中的值(itervalues返回值的迭代器)。与返回键的列表不同的是,返回值的列表中可以包含重复的元素
>>> d = {}
>>> d[1] = 1
>>> d[2] = 2
>>> d[3] = 3
>>> d[4] = 1
>>> d.values()
[1, 2, 3, 1]
>>> it = d.itervalues()
>>> it
<dictionary-valueiterator object at 0xa05ac34>
>>> list(it)
[1, 2, 3, 1]