# coding:utf-8
#--------------------------------------------- 创建和使用字典 ---------------------------------------------
#电话簿示例
names = ['Alice', 'Neth', 'Cecil', 'Dee-Dee', 'Earl']
numbers = ['2341', '9102', '3158', '0142', '5551']
print numbers[names.index('Cecil')] ##查找Cecil电话,列表方式,希望字典方式:phonebook['Cecil']
#3158
#字典方式
phonebook = {'Alice': '2341', 'Beth': '9102', 'Cecil': '3158'} #名字是键,电话是值,键是唯一的,值不是唯一的。
print phonebook['Cecil']
#3158
#dict
#可以用dict函数通过其他映射或者对的序列建立字典
items = [('name', 'Gumby'), ('age', 42)]
d = dict(items)
print d
#{'age': 42, 'name': 'Gumby'}
d = dict(name='Gumby', age=42) #也可以通过关键字参数来创建字典
print d
#{'age': 42, 'name': 'Gumby'}
#x = []
#x[42] = 'foobar' #字符串foor关联到一个空列表42号位置上,显然是不可能的,因为这个位置根本不存在。为了将变成可能,我必须用[None]*43
x = {}
x[42] = 'foobar' #字典可以,我将'foobar'关联到空字典的键42上
print x
#{42: 'foobar'}
#字典的格式化字符串
#如果使用的是字典(以字符串作为键)而不是元组,使用字符串格式化方式更酷一些,在每个转换说明符中的%字符后面,可以加上键(用圆括号括起来),后面再跟上其他说明元素。
phonebook = {'Alice': '2341', 'Beth': '9102', 'Cecil': '3158'}
print "Cecil's phone number is %(Cecil)s." % phonebook #百分号后面加上键(圆括号括起来)
#Cecil's phone number is 3158.
#当以这种方式使用字典的时候,只要所有给出的键都能在字典中找到,就可以使用任意数量的转换说明符。这类字符串格式化在模板系统中非常有用。
template = '''
%(title)s
%(text)s
'''
data = {'title': 'My Home Page', 'text': 'Welcome to my home page!'}
print template % data #html例子,格式化模板很方便
#
#
#
#My Home Page
# Welcome to my home page!
#
#-------------------------------------------- 字典方法 -------------------------------------------------------
#clear
#清除字典中所有的项。这是个原地操作(类似list.sort),所以无返回值(或者说返回None)
d = {}
d['name'] = 'Gumby'
d['age'] = 42
print d
#{'age': 42, 'name': 'Gumby'}
returned_value = d.clear()
print d
#{}
print returned_value
#None
x = {}
y = x
x['key'] = 'value'
print y
#{'key': 'value'}
x = {} #x变量被清空
print y #y变量字典仍然存在,如果想彻底清空,就需要用到clear
#{'key': 'value'}
x = {}
y = x
x['key'] = 'value'
print y
#{'key': 'value'}
x.clear()
print x
#{}
print y #x和y一起被清空
#{}
#copy
#copy方法返回一个具有相同键-值对的新字典(这个方法实现的是浅复制,因为值本身就是相同的,而不是副本)。
x = {'username': 'admin', 'machines': ['foo', 'bar', 'baz']}
y = x.copy()
print y
#{'username': 'admin', 'machines': ['foo', 'bar', 'baz']}
y['username'] = 'mlh' #替换不会修改原始字典x变量
print y
#{'username': 'mlh', 'machines': ['foo', 'bar', 'baz']}
print x
#{'username': 'admin', 'machines': ['foo', 'bar', 'baz']}
y['machines'].remove('bar') #修改某个值(原地修改,而不是替换),原始字典x变量也会改变
print y
#{'username': 'mlh', 'machines': ['foo', 'baz']}
print x
#{'username': 'admin', 'machines': ['foo', 'baz']}
#避免这个问题的一种方法就是使用深复制,复制其包含的所有值。可以使用copy模块的deepcopy函数来完成操作。
#deepcopy
#深复制
from copy import deepcopy #导入copy模块的deepcopy函数
d = {}
d['names'] = ['Alfred', 'Bertrand']
c = d.copy()
dc = deepcopy(d)
d['names'].append('Clive') #原始字典变量d增加值
print d
#{'names': ['Alfred', 'Bertrand', 'Clive']}
print c #浅复制会一起增加
#{'names': ['Alfred', 'Bertrand', 'Clive']}
print dc #深复制则不会改变
#{'names': ['Alfred', 'Bertrand']}
#fromkeys
#给定的键建立新字典,每个键对应一个默认值None
print {}.fromkeys(['name', 'age']) #它首先构造空字典,然后调用fromkeys方法建立另外一个词典---有些多余。建议用dict方法
#{'age': None, 'name': None}
print dict.fromkeys(['name', 'age']) #dict方法,效果和上面一样。建议使用。
#{'age': None, 'name': None}
print dict.fromkeys(['name', 'age'], '(unknown)') #如果不想使用None作为默认值,也可以自己提供默认值。
#{'age': '(unknown)', 'name': '(unknown)'}
#get
#更宽松的访问字典方法,一般访问不存在的项会报错,get访问不会报错,得到None
d = {}
#print d['name'] #这样访问会报错
print d.get('name') #get不会报错,返回None
#None
print d.get('name', 'N/A') #也可以自定义None,改成N/A,如果键在不会替换
#N/A
d['name'] = 'Eric'
print d.get('name') #如果键存在,get用起来和普通字典查询一样
#Eric
print d.get('name', 'N/A') #如果键存在,不会替换
#Eric
#has_key
#检查有没键
d = {}
print d.has_key('name') #没有键
#False
d['name'] = 'Eric'
print d.has_key('name') #有键
#True
#items和iteritems
#items将字典所有的项以列表方法返回,列表中的每一项都表示为(键,值)队的形式。但是项在返回时并没有遵循特定的次序。
d = { 'title': 'Python Web Site', 'url': 'http://www.python.org', 'spam': 0 }
print d.items()
#[('url', 'http://www.python.org'), ('spam', 0), ('title', 'Python Web Site')]
#iteritems方法的作用大致相同,但是会返回一个迭代器对象而不是列表:
it = d.iteritems() #返回迭代器
print it
#
print list(it) #转换为列表
#[('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 }
print d.keys() #将字典中的键以列表形式返回
#['url', 'spam', 'title']
it = d.iterkeys() #返回迭代器
print it
#
print list(it) #转换为列表
#['url', 'spam', 'title']
#values和itervalues
#valuse方法以列表的形式返回字典中的值,与返回键的列表不同的是,返回值的列表中可以包含重复的元素。itervalues则返回值的迭代器。
d = {}
d[1] = 1
d[2] = 2
d[3] = 3
d[4] = 1
print d.values()
#[1, 2, 3, 1]
it = d.itervalues() #返回迭代器
print it
print list(it) #转换为列表
#
#pop
#移除键和值
d = {'x': 1, 'y': 2}
d.pop('x') #删除x键和值
print d
#{'y': 2}
#popitem
#随机删除
d = {'x': 1, 'y': 2 ,'z': 3}
d.popitem() #随机删除一个,好处不用指定键,字典没有顺序概念,若想一个个移除,这个方法非常有效。
print d
#{'x': 1, 'z': 3}
#setdefault
#类似get方法,在没有键情况下可以设定相应键
d = {}
d.setdefault('name', 'N/A')
print d
#{'name': 'N/A'}
d['name'] = 'Gumby'
d.setdefault('name', 'N/A') #有键不会替换
print d
#{'name': 'Gumby'}
#update
#一个字典更新到另一个字典
d = {
'x': '1',
'y': '2',
'z': '3'
}
e = {'a': '4'}
d.update(e)
print d
#{'y': '2', 'x': '1', 'z': '3', 'a': '4'}
#涉及的函数
#dict(seq) 用(键,值)对(或者映射和关键字参数)建立字典