开始 python 从入门到精通 Dictionaries(字典)

Dictionary Uses

名称字典应该会给你关于这个结构的用途的线索。一本普通的书是为从头到尾阅读而制作的。如果您愿意,您可以快速打开它到任何给定的页面。这有点像Python列表。另一方面,实际字典和Python等价词典的构造都是为了便于查找特定单词(键)以找到其定义(值)。

在许多情况下,字典比列表更合适。这里有一些用法的例子Python字典:

  • 表示游戏板的状态,每个键都是坐标的元组
  • 以文件名作为键存储文件修改时间
  • 数字电话/通讯录

假设你有一个人的列表。

>>> names = ['Alice', 'Beth', 'Cecil', 'Dee-Dee', 'Earl']


如果您想创建一个小数据库来存储它们的电话号码呢人们,你会怎么做?一种方法是再列一个清单。假设你只存储它们四位数的扩展。然后你会得到这样的结果:

>>> numbers = ['2341', '9102', '3158', '0142', '5551']
一旦你创建了这些列表,你可以查找塞西尔的电话号码如下:

>>> numbers[names.index('Cecil')]
'3158
这是可行的,但有点不切实际。你真正想要做的是如下的事情:

>>> phonebook['Cecil']
'3158
你猜怎么着?如果电话簿是一本字典,你就可以这样做。

 

Creating and Using Dictionaries

字典是这样写的:

phonebook = {'Alice': '2341', 'Beth': '9102', 'Cecil': '3258'}
 

字典由键及其对应的值对(称为项)组成。在本例中,是名称是键,而电话号码是值。每个键与其值之间用冒号(:)分隔,项目用逗号分隔,整个部分用大括号括起来。一个空的字典(没有任何项)是用两个花括号编写的,像这样:{}。

 

The dict Function 


可以使用dict function1从其他映射(例如,other)构造字典字典)或(键、值)对序列。

>>> items = [('name', 'Gumby'), ('age', 42)]
>>> d = dict(items)
>>> d
{'age': 42, 'name': 'Gumby'}
>>> d['name']
'Gumby'

它也可以用于关键字参数,如下:

>>> d = dict(name='Gumby', age=42)
>>> d
{'age': 42, 'name': 'Gumby'}
 

尽管这可能是dict最有用的应用程序,但也可以将它与映射参数一起使用,以创建具有与映射相同项字典。(如果使用不带任何参数,它会返回一个新的空字典,就像其他类似的功能,比如列表、元组,和str)如果其他映射字典(毕竟,这是唯一内置映射类型),你可以使用字典方法复制相反,如在本章后面所述。

 

Basic Dictionary Operations
 

字典的基本行为在很多方面反映了序列的基本行为。

  • len(d)返回d中的项数(键值对)。
  • d[k]返回与键k相关联的值。
  • d[k] = v将值v与键k关联起来
  • 删除键为k的项。
  • d中的k检查d中是否有一个项的键值为k。

第一点——键可以是任何不可变类型——是字典的主要优势。第二点也很重要。看看这里的区别:

>>> x = []
>>> x[42] = 'Foobar'
Traceback (most recent call last):
File "<stdin>", line 1, in ?
IndexError: list assignment index out of range
>>> x = {}
>>> x[42] = 'Foobar'
>>> x
{42: 'Foobar'}
 

首先,我尝试分配字符串'Foobar'位置42在一个空列表显然不可能,因为该位置不存在。为了使这成为可能,我必须用[None] * 43或其他东西来初始化x,而不是简单地用[]。然而,下一次尝试非常成功。这里我将'Foobar'赋值给一个空字典的键42。您可以看到这里没有问题。一个新条目被简单地添加到字典中,我就开始工作了。

 

Listing 4-1. Dictionary Example
 

# A simple database
# A dictionary with person names as keys. Each person is represented as
# another dictionary with the keys 'phone' and 'addr' referring to their phone
# number and address, respectively.
people = {
'Alice': {
'phone': '2341',
'addr': 'Foo drive 23'
},
'Beth': {
'phone': '9102',
'addr': 'Bar street 42'
},
'Cecil': {
'phone': '3158',
'addr': 'Baz avenue 90'
}
}
# Descriptive labels for the phone number and address. These will be used
# when printing the output.
labels = {
'phone': 'phone number',
'addr': 'address'
}
name = input('Name: ')
# Are we looking for a phone number or an address?
request = input('Phone number (p) or address (a)? ')
# Use the correct key:
if request == 'p': key = 'phone'
if request == 'a': key = 'addr'
# Only try to print information if the name is a valid key in
# our dictionary:
if name in people: print("{}'s {} is {}.".format(name, labels[key], people[name][key]))

运行结果:

 

 

 

String Formatting with Dictionaries
 

 在第3章中,您看到了如何使用字符串格式来格式化作为format方法的单个(命名或未命名)参数提供的值。有时,以字典的形式收集一组命名值会使事情变得更简单。例如,字典可能包含所有类型的信息,而您的格式字符串将只挑选出它需要的任何信息。您必须通过使用format_map指定要提供一个映射。

>>> phonebook
{'Beth': '9102', 'Alice': '2341', 'Cecil': '3258'}
>>> "Cecil's phone number is {Cecil}.".format_map(phonebook)
"Cecil's phone number is 325


在使用这样的字典时,您可以使用任意数量的转换说明符,只要给定的所有键可以在字典中找到。这种字符串格式在模板系统中非常有用例中使用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>
 

Dictionary Methods

与其他内置类型一样,字典也有方法。虽然这些方法可能非常有用,但您需要可能不像列表和字符串方法那样经常需要它们。你可能想要先浏览这一部分先了解哪些方法是可用的,然后如果需要确切地了解如何使用给定的方法。

 

clear


clear方法从字典中删除所有项。这是一个就地操作(如list.sort),所以它不返回任何东西(或者更确切地说,没有)。

>>> d = {}
>>> d['name'] = 'Gumby'
>>> d['age'] = 42
>>> d
{'age': 42, 'name': 'Gumby'}
>>> returned_value = d.clear()
>>> d
{}
>>> print(returned_value)
None

为什么这个有用?让我们考虑两种情况。这是第一个:

>>> x = {}
>>> y = x
>>> x['key'] = 'value'
>>> y
{'key': 'value'}
>>> x = {}
>>> x = {}
{'key': 'value'}


这是第二种情况:

>>> x = {}
>>> y = x
>>> x['key'] = 'value'
>>> y
{'key': 'value'}
>>> x.clear()
>>> y
{}
在这两种情况下,x和y最初指的是同一个字典。在第一个场景中,我通过给x分配一个新的空字典来空白x。这一点也不影响y,它仍然是指原始的字典。这可能是您想要的行为,但如果您确实想删除原始字典的所有元素,则必须使用clear。正如您在第二个场景中看到的,随后y也是空的。

 

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']}

可以看到,当替换副本中的值时,原始值不受影响。但是,如果您修改了一个值(在适当的位置,而不是替换它),原始值也会改变,因为相同的值存储在那里(如本例中的'machines'列表)。避免这个问题的一种方法是进行深度复制,复制值及其包含的任何值,等等。您可以使用复制模块中的函数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方法使用给定的键创建一个新的字典,每个键都有一个默认的对应值

>>> {}.fromkeys(['name', 'age'])
{'age': None, 'name': None}


本例首先构造一个空字典,然后调用该空字典上的fromkeys方法,以创建另一个字典(这是一个有点冗余的策略)。相反,您可以直接在dict上调用该方法,dict(如前所述)是所有字典的类型。(类型和类的概念将在第7章中更深入地讨论。)

>>> 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 ?
KeyError: 'name


get不是这样的。

>>> print(d.get('name'))
None
 

如您所见,当您使用get访问一个不存在的密钥时,不会出现异常。相反,您得到的值是None。您可以提供自己的默认值,然后使用该值而不是None。

>>> d.get('name', 'N/A')
'N/A
如果键存在,get就像普通的字典查找一样工作。

>>> d['name'] = 'Eric'
>>> d.get('name')
'Eric
 

Listing 4-2显示了清单4-1中程序的修改版本,它使用get方法访问数据库条目。

# A simple database using get()
# Insert database (people) from Listing 4-1 here.
labels = {
'phone': 'phone number',
'addr': 'address'
}
name = input('Name: ')
# Are we looking for a phone number or an address?
request = input('Phone number (p) or address (a)? ')
# Use the correct key:
key = request # In case the request is neither 'p' nor 'a'
if request == 'p': key = 'phone'
if request == 'a': key = 'addr'
# Use get to provide default values:
person = people.get(name, {})
label = labels.get(key, key)
result = person.get(key, 'not available')
print("{}'s {} is {}.".format(name, label, result))

下面是该程序的运行示例。注意,即使用户输入的值是我们没有准备好的,get增加的灵活性也允许程序给出有用的响应

items


items方法以项目列表的形式返回字典中的所有项目,其中每个项目的形式(键、值)。这些items不会以任何特定的顺序返回。

>>> d = {'title': 'Python Web Site', 'url': 'http://www.python.org', 'spam': 0}
>>> d.items()
dict_items([('url', 'http://www.python.org'), ('spam', 0), ('title', 'Python Web Site')])


返回值是一种特殊类型,称为字典视图。字典视图可以用于迭代(更多信息请参见第5章)。此外,您还可以确定其长度并检查其成员资格。

>>> it = d.items()
>>> len(it)
3
>>> ('spam', 0) in it
True
视图的一个有用之处是它们不复制任何东西;它们总是反映底层字典,即使您修改了它

>>> d['spam'] = 1
>>> ('spam', 0) in it
False
>>> d['spam'] = 0
>>> ('spam', 0) in it
True
但是,如果您希望将这些项复制到列表中(在较旧版本的Python中使用项时就会发生这种情况),那么您总是可以自己完成这项工作。

>>> list(d.items())
[('spam', 0), ('title', 'Python Web Site'), ('url', 'http://www.python.org')]

 

keys

keys方法返回字典中键的字典视图。

pop

pop方法可用于获得与给定键值对应的值,然后删除键值字典里的一对。

>>> d = {'x': 1, 'y': 2}
>>> d.pop('x')
1
>>> d
{'y': 2}

 

popitem

popitem方法类似于list。pop,它弹出列表的最后一个元素。与列表。然而,popitem从任意项中弹出,因为字典没有最后一个元素或任何顺序。如果您希望以有效的方式逐个删除和处理项(不需要首先检索键的列表),那么这可能非常有用。

>>> d = {'url': 'http://www.python.org', 'spam': 0, 'title': 'Python Web Site'}
>>> d.popitem()
('url', 'http://www.python.org')
>>> d
{'spam': 0, 'title': 'Python Web Site'}
尽管popitem类似于列表方法pop,但是没有与append(将元素添加到列表末尾)等价的字典。因为字典没有顺序,所以这样的方法没有任何意义。

 

setdefault

setdefault方法与get有点类似,因为它检索与给定键相关联的值。除了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返回默认值并相应地更新字典。如果键存在,则返回其值,字典将保持不变。默认值是可选的,与get一样;如果它被省略,则不使用。

>>> d = {}
>>> print(d.setdefault('name'))
None
>>> d
{'name': None}
 

update

update方法用另一个字典的条目更新一个字典

>>> 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
{'url': 'http://www.python.org', 'changed':
'Mar 14 22:09:15 MET 2016', 'title': 'Python Language Website'}


将提供的字典中的项添加到旧字典中,用相同的键替换其中的任何项。可以使用与dict函数(或类型构造函数)相同的方式调用update方法,正如本章前面讨论的那样。这意味着可以使用(键、值)对或关键字参数的映射、序列(或其他可迭代对象)来调用update。


values

values方法返回字典中值的字典视图。与键不同,值返回的视图可能包含重复的值。

>>> d = {}
>>> d[1] = 1
>>> d[2] = 2
>>> d[3] = 3
>>> d[4] = 1
>>> d.values()
dict_values([1, 2, 3, 1])
 

参考:Beginning Python From Novice to Professional, 3rd Edition 第四章

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值