Python基础教程(第2版)第四章 字典:当索引不好用时

1.字典

字典是一种通过名字引用值的数据结构,字典中的值并没有特殊的顺序,但是都存储在一个特点的键(key)中,key可以是数字、字符串甚至元组

        由多个键及其对应的值构成的键值对组成
        每个键值对用逗号隔开,键和它的值用冒号隔开
        字典中的键是唯一的,而值并不唯一

phonebook={}	#空字典
print(phonebook)	#{}
phonebook={'Alice':'2341','Beth':'9102','Cecil':'3258'}	
print(phonebook)	#{'Alice': '2341', 'Beth': '9102', 'Cecil': '3258'}

dict函数:通过其他映射(如字典)或(键,值)这样的序列对来建立字典

如果dict函数不带任何参数,则返回一个新的空字典

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

2.基本的字典操作

宇典的基本行为在很多方面与序列 (sequence)类似:

        len(d):返回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为列表)
则用来查找值,而不是索引(在字典中检查键的成员资格比在列表中检查值的成员资格更高效)

#程序示例:使用人名作为键的字典,每个人用另一个字典来表示,其键“phone”和“addr”分別表示他们的电话号码和地址
people={
	'Alice':{
		'phone':'2341',
		'addr':'Foo drive 23'
	},
	'Beth':{
		'phone':'9102',
		'addr':'Bar street 42'
	},
	'Cecil':{
		'phone':'3258',
		'addr':'Baz avenue 90'
	}
}
#针对电话号码和地址使用的描述性标签,会在打印输出的时候用到
labels = {
	'phone':'phone number',
	'addr': 'address'
}
# name=input('Name:')
name='Beth'
#查找电话号码还是地址?使用正确的鍵:
# request=input("Phone number (p) or address (a)? ")
request='p'
if request == 'p':
	key = 'phone'
if request == 'a':
	key = 'addr'
# 如果名字是字典中的有效键才打印信息:
if name in people: 
	print("%s’s %s is %s." %(name,labels[key],people[name][key]))	#Beth’s phone number is 9102.

3.字典的格式化字符串:%(键)说明元素

print("Cecil's phonenumber is %(Cecil)s." % phonebook)	#Cecil's phonenumber is 3258.

4.字典方法

get函数:当访问的是一个不存在的键时,get不会提示异常,而是返回None值

        可以自定义默认值替换None

d={}
print(d.get('name'))	#None
print(d.get('name','N/A'))	#N/A
#程序示例:使用get()的简单数据库
people={
	'Alice':{
		'phone':'2341',
		'addr':'Foo drive 23'
	},
	'Beth':{
		'phone':'9102',
		'addr':'Bar street 42'
	},
	'Cecil':{
		'phone':'3258',
		'addr':'Baz avenue 90'
	}
}
#针对电话号码和地址使用的描述性标签,会在打印输出的时候用到
labels = {
	'phone':'phone number',
	'addr': 'address'
}
# name=input('Name:')
name='Beth'
#查找电话号码还是地址?使用正确的鍵:
# request=input("Phone number (p) or address (a)? ")
request='batting average'
key=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')
if name in people: 
	print("%s’s %s is %s." %(name,label,result))	#Beth’s batting average is not available.

clear函数:清除字典中所有的项,无返回值

d.clear()
print(d)	#{}

copy函数:返回一个具有相同键值对的新字典(浅复制)

x={'username':'admin','machines':['foo','bar','baz']}
y=x.copy()
print("浅复制前x:",x)	#浅复制前x: {'username': 'admin', 'machines': ['foo', 'bar', 'baz']}
print("浅复制前y:",y)	#浅复制前y: {'username': 'admin', 'machines': ['foo', 'bar', 'baz']}
y['username']='mlh'
y['machines'].remove('bar')
print("浅复制后x:",x)	#浅复制后x: {'username': 'admin', 'machines': ['foo', 'baz']}
print("浅复制后y:",y)	#浅复制后y: {'username': 'mlh', 'machines': ['foo', 'baz']}

可以看到,当在副本中替换值的时候,原始字典不受影响,但是如果修改了某个值(原地
修改,而不是替换),原始的字典也会改变,因为同样的值也存储在原宇典中

为了避免这种问题,可以使用deepcopy函数,实现字典的深复制

from copy import deepcopy
d['names']=['Alfred','Bertrand']
c=d.copy()
dc=deepcopy(d)
print("深复制前d: ",d)	#深复制前d:  {'names': ['Alfred', 'Bertrand']}
print("深复制前c: ",c)	#深复制前c:  {'names': ['Alfred', 'Bertrand']}
print("深复制前dc:",dc)	#深复制前dc: {'names': ['Alfred', 'Bertrand']}
d['names'].append('Clive')
print("深复制后d: ",d)	#深复制后d:  {'names': ['Alfred', 'Bertrand', 'Clive']}
print("深复制后c: ",c)	#深复制后c:  {'names': ['Alfred', 'Bertrand', 'Clive']}
print("深复制后dc:",dc)	#深复制后dc: {'names': ['Alfred', 'Bertrand']}

fromkeys函数:使用给定的键建立新的字典,每个键默认对应值为None

        还可以直接提供默认值

print({}.fromkeys(['name','age']))	#{'name': None, 'age': None}
print(dict.fromkeys(['name','age'],'(unknown)'))		#{'name': '(unknown)', 'age': '(unknown)'}	#(dict表示字典类)

在Python2中提供了has_key函数:检查字典中是否含有给出的键,相当于'name' in d

d={}
print("has_key函数:",d.has_key('name'))

在Python2中,items函数将所有的字典项以列表方式返回(项在返回时并没有特殊的顺序),这些列表项中的每一项都来自于(键,值),而iteritems函数将所有的字典项以迭代器方式返回

在Python3中,items函数将所有的字典项以迭代器方式返回,可用于for循环遍历

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

pop函数:将键值对从字典中移除,并返回该键对应的值

popitem函数:移除字典中的最后一个元素(相当于随机项,因为字典中并没有顺序的概念)

print("从d中移除",d.pop('url'),"后的d:",d)	#从d中移除 http://www.python.org 后的d: {'title': 'Python Web Site', 'spam': 0}
print("从d中移除",d.popitem(),"后的d:",d)		#从d中移除 ('spam', 0) 后的d: {'title': 'Python Web Site'}

setdefault函数:获取给定键的值,当键不存在时会在字典中插入该键并设定默认值

d={}
print("setdefault前的d:",d)	#setdefault前的d: {}
print("不含有给定键时,setdefault返回的是:",d.setdefault('name','N/A'))	#不含有给定键时,setdefault返回的是: N/A
print("setdefault后的d",d)	#setdefault后的d {'name': 'N/A'}
d['name']='Gumby'
print("含有给定键时,setdefault返回的是:",d.setdefault('name','N/A'))	#含有给定键时,setdefault返回的是: Gumby

update函数:利用一个字典更新另一个字典

d={'title':'Python Web Site','url': 'http://www.python.org','changed':'Mar 14 22:09:15 MET 2008'}
x={'title':'Python Language Site'}
print("更新前的d:",d)	#更新前的d: {'title': 'Python Web Site', 'url': 'http://www.python.org', 'changed': 'Mar 14 22:09:15 MET 2008'}
d.update(x)
print("更新后的d:",d)	#更新后的d: {'title': 'Python Language Site', 'url': 'http://www.python.org', 'changed': 'Mar 14 22:09:15 MET 2008'}

Python3中,values函数以迭代器的形式返回字典中的值(Python2返回的是列表)

print(d.values())	#dict_values(['Python Language Site', 'http://www.python.org', 'Mar 14 22:09:15 MET 2008'])

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值