Python基础教程 | 第四章 字典

第四章 字典

1 略去

2 创建和使用字典

  • 字典,通过 名字 引用 的一种数据结构,这种数据结构成为 映射(mapping),其中key唯一,而 值 不一定;
  • 没有特定顺序,但都存储在一个特定的 键(key)中,键可以是数字、字符串、元组;
  • 键—值 序列对称为 项;
  • 字典构成:a_dict = {key_1:value_1, key_2, value_2,……},可以通过key来引用value,反之则不可以;
#实现电话号码索引
>>> name = ['Tom', 'Lily', 'John', 'Jenny']
>>> phone = ['0123', '1234', '2345', '3456']
#查找John的电话号码
>>> phone[name.index('John')]
'2345'
#注意电话号码不要用 数字 表示,因为八进制数字都是以0开头的
2.1 dict函数

通过其他映射(如字典)或(键,值)序列对来创建字典

# 方法1
>>> items = [('John', '0123'), ('Tom', '1234'), ('Matt', '2345')]
>>> a_dict = dict(items)
>>> a_dict
{'Matt': '2345', 'John': '0123', 'Tom': '1234'}

# 方法2
>>> d = dict(name = 'John', age = '42')
>>> d
{'age': '42', 'name': 'John'}

# 方法3
>>> dict = {'John':'0123', 'Tom':'1234', 'Matt':'2345'}
>>> dict
{'Matt': '2345', 'John': '0123', 'Tom': '1234'}

# dict[key_name]→调用对应的value
>>> dict['John']
'0123'
2.2 基本字典操作
>> d = {'John':'0123', 'Tom':'1234', 'Matt':'2345'}
>>> len(d)              #返回d中 项 的个数
3
>>> d['Tom'] = '4321'   #将 value 赋给 key
>>> d['Tom']            #调用 key 对应的 value
'4321'
>>> del d['Tom']        #删除 项
>>> d['Rober'] = '3456' #添加 项
>>> d 
{'Matt': '2345', 'John': '0123', 'Rober': '3456'}
>>> 'Tom' in d          #成员资格
False

字典与列表的重要区别:
- 键类型:key不一定是整型数据,也可能是其他不可变类型,如浮点型(实型)、字符串或元组;

>>> a_list = []
>>> a_list[3] = 'John'
IndexError: list assignment index out of range

>>> b_list = 5*[None]   #建立含有5个空元素的列表
>>> b_list[3] = 'John'
>>> b_list
[None, None, None, 'John', None]

>>> a_dict = {}
>>> a_dict[3] = 'John'  #此处的 3 是key,不是编号
>>> a_dict['name'] = 'Tom'
>>> a_dict
{3: 'John', 'name': 'Tom'}
  • 自动添加:可以通过为 key 指定 value 来添加新项,值 也不能关联到列表之外的索引上;
  • 成员资格:检查的是 key 而不是 value,list 中 value in list 查找的是 value;
  • 字典中检查 key 的成员资格的效率要比 list 高效;

【例子】代码清单4-1 电话簿

#一个用于查找people电话号码和地址的程序
#创建用户信息库
user_info = {
'John':{'phone':'0123','addr':'J'},
'Tom':{'phone':'1234','addr':'T'},
'Lily':{'phone':'2345','addr:'L'},
'Matt':{'phone':'3456','addr':'M'},
'Robert':{'phone':'4567','addr':'R'}
}

label = {
    'phone':'phone number',
    'addr':'address'
}
#上述两个字典公用的 key 相同

#获取用户需求
name = raw_input('Name: ')
choice = raw_input('The info you needed, phone number(P) or address(A): ')

if choice == 'P': key = 'phone'
if choice == 'A': key = 'addr'

print "%s's %s is %s." % (name, label[key], user_info[name][key]) 

#注意最后的user_info[name][key],是先查找到了user_info 中的 name,然后又查找到了 name 中的 key 对应的 值。
-----------------------------------------------------
运行结果:
Name: Matt
The info you needed, phone number(P) or address(A): P
Matt's phone number is 3456.
-----------------------------------------------------
2.3 字典的格式化字符串

字符串键:print “%(key)s” % a_dict,调用 a_dict 中 key 对应的 value。
注意:
- a_dict 只以字符串作为 key;
- 括号(key)中的字符串格式的 key 不用加引号

>>> phone_book = {'John':'0123', 'Lily':'1234', 'Tom':'2345', 'Robert':'3456'}
>>> print "Tom's phone number is %(Tom)s." % phone_book
Tom's phone number is 2345.

>>> print "%(Robert)s and %(Lily)s" % phone_book   #后面只能跟一个字典
3456 and 1234

# 转换符 % 后面貌似只能跟一个字典,多个时加( )、顺次排列也行不通;
>>> address = {'John':'J', 'Lily':'L', 'Tom':'T', 'Robert':'R'}
>>> print "Tom's phone number is %(Tom)s and address is %(Tom)s" % (phone_book, address)   #使用()排列多个字典也不行
TypeError: format requires a mapping
# 以上述电话簿为例
>>> user_info
{
'Matt': {'phone': '3456', 'addr': 'M'}, 
'John': {'phone': '0123', 'addr': 'J'}, 
'Robert': {'phone': '4567', 'addr': 'R'}, 
'Tom': {'phone': '1234', 'addr': 'T'}
}

>>> print "%(Matt[phone])s" % user_info
KeyError: 'Matt[phone]'
# 错误:Matt[phone]对应的是子字典Matt中的phone的 值,其不是user_info中的一个key;

>>> print "%(phone)s" % user_info['Matt']
3456
# 此时的 phone 是user_info['Matt']中的 key;
# user_info['Matt']对应的是Matt信息的子字典;
# 将上述电话簿例子中最后的print改为如下,则会出错:
>>> print "Matt's phone number is %(key)s." % user_info[name]
KeyError: 'key'
# 因为 key 本身不是 字符串,虽然 key = 'phone'(or address,此处为了方便)
# 故在字符串键中 key 必须是字符串,改为如下则正确了:
>>> print "Matt's phone number is %(phone)s." % user_info[name]

3 字典方法

3.1 clear

清除字典中所有项,无返回值

>>> a_dict = {}
>>> a_dict['name'] = 'John'
>>> a_dict['age'] = 23
>>> a_dict
{'age': 23, 'name': 'John'}
>>> a_dict.clear()
>>> a_dict
{}

考虑下面两种情况:

第一种情况
>>> a_dict = {'name':'John', 'age':23}
>>> b_dict = a_dict
>>> a_dict = {}     #通过关联到空字典{}来清空a_dict
>>> a_dict
{}
>>> b_dict          #但是对复制的b_dict没有影响
{'age': 23, 'name': 'Tom'}

第二种情况
>>> a_dict = {'name':'John', 'age':23}
>>> b_dict = a_dict
>>> a_dict.clear()  #使用clear函数来清空字典
>>> a_dict
{}
>>> b_dict          #复制的b_dict也没清空
>{}
3.2 copy

浅复制替换副本中的 值 的时候,原字典不受影响;修改副本中 值 的时候,原字典也跟着改变;

>>> a_dict = {'name':'John', 'info':[23, 'Beijing', 'male']}
>>> b_dict = a_dict.copy()
>>> b_dict['name'] = 'Tom'          #替换
>>> b_dict['info'].remove('male')   #修改
>>> b_dict
{'info': [23, 'Beijing'], 'name': 'Tom'}
>>> a_dict
{'info': [23, 'Beijing'], 'name': 'John'}

深复制:副本与原字典间互不影响;

>>> from copy import deepcopy
>>> a_dict = {'name':'John', 'info':[23, 'Beijing', 'male']}
>>> b_dict = deepcopy(a_dict)
>>> a_dict['info'].append('rich')
>>> a_dict
{'info': [23, 'Beijing', 'male', 'rich'], 'name': 'John'}
>>> b_dict     # a_dict 和 b_dict 互不影响
{'info': [23, 'Beijing', 'male'], 'name': 'John'}
3.3 fromkeys

使用给定的 键 创建字典,每个 键 默认对应的 值 为None.

>>> {}.fromkeys(['name', 'age', 'gender'])    #方法1
{'gender': None, 'age': None, 'name': None}

>>> dict.fromkeys('name', 'address', 'phone') #方法2
TypeError: fromkeys expected at most 2 arguments, got 3

>>> dict.fromkeys(['name', 'age'])   #【疑问】用方法2时最多有2个key
{'age': None, 'name': None}

#将 key 的值初始化
>>> dict.fromkeys(['name', 'age'], '(unknow)') 
{'age': '(unknow)', 'name': '(unknow)'}
3.4 get

访问字典项的方法,即便 不存在,也不会出错.

>>> a_dict = dict.fromkeys(['name', 'age', 'gender'], 'hihi')

>>> a_dict['address']
KeyError: 'address'

>>> print a_dict.get('address')
None
>>> print a_dict.get('name')
hihi

【重要】a_dict.get(key, value)相当于一个if…else…语句——当key in a_dict,返回 key 对应的 值,当 key 不在字典中时,则返回提供的value——原文链接

>>> a_dict = {'name':'John', 'age':23}
>>> print a_dict.get('name', 'none')    #key in  a_dict
John
>>> print a_dict.get('address', 'error')#key 不在a_dict中
error
>>> a_dict
{'age': 23, 'name': 'John'}

代码清单4-1 电话簿为例:

user_info = {
'John':{'phone':'0123','addr':'J'},
'Tom':{'phone':'1234','addr':'T'},
'Lily':{'phone':'2345','addr':'L'},
'Matt':{'phone':'3456','addr':'M'},
'Robert':{'phone':'4567','addr':'R'}
}

label = {
    'phone':'phone number',
    'addr':'address'
}
# 上述两个字典公用的 key 相同
# 获取用户需求
name = raw_input('Name: ')
choice = raw_input('The info you needed, phone number(P) or address(A): ')

key = choice   # 当choice不是P或A时
if choice == 'P': key = 'phone'
if choice == 'A': key = 'addr'

person = user_info.get(name, {})   
# 如果name in user_info, 则返回其name;反之,name = {}
phone_or_addr = label.get(key, key)        
# 当key不在label中时,返回(从用户获得的)key
result = user_info[name].get(key, 'not available')
# 当key不存在与user_info[name]时,返回'not available'
print "%s's %s is %s." % (name, phone_or_addr, result) 

--------------------------------------------------------------
运行结果:
Name: John
The info you needed, phone number(P) or address(A): P
John's phone number is 0123.

Name: Matt
The info you needed, phone number(P) or address(A): you choose
Matt's you choose is not available.
--------------------------------------------------------------
3.5 has_key

a_dict has_key(key) == key in a_dict;
python2.7.9中及3.0以后不支持该函数;

3.6 items and iteritems
  • items将字典项以列表方式返回,列表中的每一项都来自(键,值);
    • 【后续】items()和iteritems()方法都普遍用于for循环的迭代中,不同的是items()返回的是列表对象,而iteritems()返回的是迭代器对象。两者用法相近,但iteritems()的性能更快——原文链接

>>> a_dict = {'name':'John', 'age':23, 'gender':'male'}
>>> a_list  = a_dict.items()
>>> a_list
[('gender', 'male'), ('age', 23), ('name', 'John')]
>>> a_dict = {'name':'John', 'age':23, 'gender':'male'}
>>> a_iterator = a_dict.iteritems()
>>> a_iterator
<dictionary-itemiterator object at 0x02325600>
>>> list(a_iterator)         #将迭代器转换为list
[('gender', 'male'), ('age', 23), ('name', 'John')]
3.7 keys and iterkeys
keys 将字典中的 键 以列表形式返回,与 fromkeys 对应; iterkeys 则返回针对 键 的迭代器;
>>> a_dict = {'name':'John', 'age':23, 'gender':'male'}
>>> a_list = a_dict.keys()
>>> a_list
['gender', 'age', 'name']
>>> a_iterator = a_dict.iterkeys()
>>> a_iterator
<dictionary-keyiterator object at 0x023322D0>
>>> list(a_iterator)
['gender', 'age', 'name']
3.8 pop
pop 获取 key 对应的 value,并将key-value删除;
>>> a_dict = {'name':'John', 'age':23, 'gender':'male'}
>>> a_dict.pop('age')
23
>>> a_dict
{'gender': 'male', 'name': 'John'}
3.9 popitem
  • popitem 返回并删除字典中随机的一 项,类似 list.pop(删除最后一项);
  • 可以用于一个一个删除字典中的项;
>>> a_dict = {'name':'John', 'age':23, 'gender':'male'}
>>> a_dict.popitem()
('gender', 'male')
>>> a_dict
{'age': 23, 'name': 'John'}
3.10 setdefault
  • 当 键 存在的时候,setdefault 返回 key 对应的 value,不改变字典;
  • 当 键 不存在的时候,setdefault 返回默认值并更新字典;
>>> a_dict = {'name':'John', 'age':23, 'gender':'male'}
>>> a_dict.setdefault('phone', '1234')  #key phone不存在
'1234'
>>> a_dict.setdefault('name', 'users')  #key name存在
'John'
>>> a_dict
{'gender': 'male', 'age': 23, 'name': 'John', 'phone': '1234'}
3.11 update

update 利用一个字典项更新另一个字典;

>>> a_dict = {'name':'John', 'age':23, 'gender':'male'}
>>> b_dict = {'name':'Tom'}
>>> a_dict.update(b_dict)   # b_dict 中的 键 存在于 a_dict中
>>> a_dict
{'gender': 'male', 'age': 23, 'name': 'Tom'}
>>> c_dict = {'gender':'female', 'phone':'1234'}   
# c_dict 中有 键 不在 a_dict 中,其对应的 项 会被更新到 a_dict 中
>>> a_dict.update(c_dict)
>>> a_dict
{'gender': 'female', 'age': 23, 'name': 'Tom', 'phone': '1234'}
3.12 values and itervalues
  • values 以列表的形式返回字典中的 值,生成的列表可以包含重复值;
  • itervalues 返回字典中 值 的迭代器;
>>> a_dict = {'name':'John', 'age':23, 'gender':'male'}
>>> a_dict.values()
['male', 23, 'John']
>>> a_dict
{'gender': 'male', 'age': 23, 'name': 'John'}
>>> a_dict.itervalues()
<dictionary-valueiterator object at 0x02325630>
>>> list(a_dict.itervalues())
['male', 23, 'John']

第四章 小节

  • 映射:可以使用不可变元素(如key)表示元素,最常用的的时字符串和元组,python中唯一内建映射是字典;
  • 利用字典格式化字符串:print “……%(key)s……” % a_dict,a_dict中的key必须都是字符串,括号中的key不加引号;
  • 本章新函数:
>>> a_dict = dict(name='John', age='24')
>>> a_dict
{'age': '24', 'name': 'John'}

>>> b_dict = dict([('name', 'John'), ('age', '24')])
>>> b_dict
{'age': '24', 'name': 'John'}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值