您的位置:首页 > 编程语言 > Python开发

Python字典

2016-01-20 15:00 585 查看
Python字典是另一种可变容器模型,且可存储任意类型对象,如字符串、数字、元组等其他容器模型。字典由键和值对组成。字典也被称为关联数组或哈希表。

注意:

每个键与值用冒号隔开,每对用逗号分割,整体放在花括号中({})

键必须唯一,但值则不必

值可以取任何数据类型,但必须是不可变的

创建字典

Python有两种方法可以创建字典,第一种是使用花括号,另一种是使用内建 函数dict

>>> info = {}
>>> info = dict()


初始化字典

Python可以在创建字典的时候初始化字典

>>> info = {"name":'cold'}
>>> info = dict(name = 'cold')   #更优雅


很明显第二种方法更加优雅和减少一些特殊字符的输入,但是有种情况第二种不能胜任

>>> key='name'
>>> info = {key:'cold'} #{'name':'cold'}
>>> info = dict(key = 'cold')   #{'key':'cold'}


明显第二种方法就会引发一个不容易找到的bug

Python字典还有一种初始化方式,就是使用字典的fromkeys方法可以从列表中获取元素作为键并用None或fromkeys方法的第二个参数初始化。

>>> info = {}.fromkeys(['name','blog'])
>>> info
{'blog':None,'name':None}
>>> info = dict().fromkeys(['name','blog'])
>>> info
{'blog':None,'name':None}
>>> info = dict().fromkeys(['name','blog'],'default')
>>> info
{'blog':'default','name':'default'}


也可以借助于zip方法进行初始化

>>> info = dict(zip(['name','blog'],['cold','linuxzen.com']))
>>> info
{'blog':'linuxzen.com','name':'cold'}


获取键值

字典可以这样获取到键的值

>>> info = {'name':'cold','blog':'linuxzen.com'}
>>> info['name']
'cold'


如果用字典里没有的键访问数据,会抛出KeyError异常。

字典有一个get方法,可以使用字典get方法更加优雅地获取字典。

>>> info = dict(name='cold',blog='www.linuxzen.com')
>>> info.get('name')
'cold'
>>> info.get('blogname')
None
>>> info.get('blogname','linuxzen')
>>> 'linuxzen'


使用get方法获取不存在的键值的时候不会触发异常,同时get方法接收两个参数,当不存在该键的时候就会返回第二个参数的值。

字典更新/添加

Python字典可以使用键作为索引来访问/更新/添加元素。

>>> info = dict()
>>> info['name'] = 'cold'
>>> info['blog'] = 'linuxzen.com'
>>> info
{'blog':'linuxzen.com','name':'cold'}
>>> info['name'] = 'cold night'
>>> info
{'blog':'linuxzen.com','name':'cold night'}


同时Python字典的update方法也可以更新和添加字典。

>>> info = dict(name = 'cold',blog = 'linuxzen.com')
>>> info.update({'name':'cold night','blogname':'linuxzen'})
>>> info
{'blog':'linuxzen.com','name':'cold night','blogname':'linuxzen'}
>>> info.update(name='cold',blog='www.linuxzen.com')    #更加优雅
{'blog':'www.linuxzen.com','name':'cold','blogname':'linuxzen'}


Python字典的update方法可以使用一个字典来更新字典,也可以使用参数传递类型dict函数一样的方式更新一个字典,上面代码中第二个跟轧机优雅,但是同样和dict函数类似,键是变量时也只取字面值。

字典删除

可以调用Python内置关键字del来删除一个键值

>>> info = dict(name = 'cold',blog = 'linuxzen.com')
>>> info
{'blog':'linuxzen.com','name':'cold'}
>>> del info['name']
{'blog':'linuxzen.com'}


同时也可以使用字典的pop方法来取出一个键值,并删除

>>> info = dict(name = 'cold',blog = 'linuxzen.com')
>>> info.pop('name')
'cold'
>>> info
{'blog':'linuxzen.com'}


存储字典

需要导入pickle模块

把字典内容存入文件

>>> import pickle
>>> f = file('data.txt','wb')
>>> pickle.dump(a,f)    #把a序列化存入文件
>>> f.close()


把内容读入字典(反序列化)

>>> a = open('data.txt','rb')
>>> print(pickle.load(a))   #把内容全部反序列化


字典遍历

其他操作

获取所有键

>>> info = dict(name = 'cold',blog = 'linuxzen.com')
>>> info.keys()
['blog','name']


获取所有值

>>> info = dict(name = 'cold',blog = 'linuxzen.com')
>>> info.values()
['cold','linuxzen.com']


判断字典中是否有该键

>>> info = dict(name = 'cold',blog = 'linuxzen.com')
>>> info.has_key('name')
True
>>> info.has_key('area')
False
>>> 'name' in info
True
>>> 'name' not in info
False


列出所有条目

>>> info = dict(name = 'cold',blog = 'linuxzen.com')
>>> info.items()
([('name', 'cold'), ('blog', 'www.linuxzen.com')]


清空字典

>>> info.clear()
>>> info
{}


浅拷贝字典

>>> info = dict(name = 'cold',blog = 'linuxzen.com')
>>> info_copy = info
>>> info_copy
{'blog':'linuxzen.com','name':'cold'}
>>> info_copy2 = info.copy()
>>> info_copy2
{'blog':'linuxzen.com','name':'cold'}


深拷贝字典

需要导入copy模块
>>> import copy
>>> fruit = {'a':'apple','b':{'g':'grape','o':'orange'}}
>>> fruit2 = copy.deepcopy(fruit)
>>> fruit3 = copy.copy(fruit)
>>> fruit2['b']['g'] = 'orange'
>>> fruit
{'b': {'g': 'grape', 'o': 'orange'}, 'a': 'apple'}
>>> fruit3['b']['g'] = 'orange'
>>> fruit
{'b': {'g': 'orange', 'o': 'orange'}, 'a': 'apple'}


比较字典

>>> cmp(a,b)


首先比较主键长度,然后比较键大小,再比较键值大小(第一个大返回1,小返回-1,一样大返回0)

以字符串形式打印字典

>>> info = dict(name = 'cold',blog = 'linuxzen.com')
>>> str(info)
"{'name': 'cold', 'blog': 'www.linuxzen.com'}"


字典长度

>>> info = dict(name = 'cold',blog = 'linuxzen.com')
>>> len(info)
2


字典键值反转

>>> info = dict(name = 'cold',blog = 'linuxzen.com')
>>> info2 = dict(zip(info.values(),info.keys()))
>>> info2
{'www.linuxzen.com': 'blog', 'cold': 'name'}


在字典中将键映射到多个值上面

我们知道,字典是一种关联容器,每个键都映射到一个单独的值上。如果想让键映射到多个值,需要将这多个值保存到另一个容器如列表或集合中。如下:

>>> d = {'a':[1,2,3],'b':[4,5]}
>>> e = {'a':{1,2,3},'b':{4,5}}


如果希望保留元素插入的顺序,就用列表;如果希望消除重复元素(且不在意它们的顺序)就用集合。

Python提供了一种更加便捷的方式去创建这样的字典,可以利用collections模块中的defaultdict类,defaultdict的一个特点就是它会自动初始化第一个值,这样只需关注添加元素即可。如下:

>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> d['a'].append(1)
>>> d['a'].append(2)
>>> d['a'].append(3)
>>> d['b'].append(4)
>>> d['b'].append(5)
>>> d
defaultdict(<class 'list'>, {'b': [4,5], 'a': [1, 2,3]})
>>> e = defaultdict(set)
>>> e['a'].add(1)
>>> e['a'].add(2)
>>> e['a'].add(3)
>>> e['b'].add(4)
>>> e['b'].add(5)
>>> e
defaultdict(<class 'set'>, {'b': {4, 5}, 'a': {1, 2, 3}})


关于defaultdict,需要注意的一个地方是,它会自动创建字典表项以待稍后的访问(即使这些表项当前在字典中还没有找到)。如果不想要这个功能,可以在普通的字典上调用setdefault()方法来取代。如:

>>> d = {}
>>> d.setfault('a',[]).append(1)
>>> d.setfault('a',[]).append(2)
>>> d.setfault('a',[]).append(3)
>>> d.setfault('b',[]).append(4)
>>> d.setfault('b',[]).append(5)
>>> d
{'b': [4, 5], 'a': [1, 2, 3]}


然而这种方法在每次调用它的时候都会创建一个初始值的新实例(例子中的空列表)

在这里,推荐使用defaultdict类,因为当我们试着自己对第一个值做初始化操作会让代码变得清晰得多:

>>> d = defaultdict(list)
>>> for key,value in pairs:
if key not in d:
d[key].append(value)


而传统方式需要这样写:

>>> d = {}
>>> for key,value in pairs:
if key not in d:
d[key] = []
d[key].append(value)


让字典保持有序

要控制字典中元素的顺序,可以使用collections模块中的OrderedDict类,当对字典做迭代时,它会严格按照元素初始添加的顺序进行。例如:

>>> from collections import OrderedDict
>>> d = OrderedDict()
>>> d['foo'] = 1
>>> d['bar'] = 2
>>> d['spam'] = 3
>>> d['grok'] = 4
>>> d
OrderedDict([('foo', 1), ('bar', 2), ('spam', 3), ('grok', 4)])
>>> for key in d:
print(key,d[key])
#Output “foo 1”,”bar 2”,”spam 3”,”grok 4”


当想构建一个映射结构以便稍后对其做序列化或编码成另一种格式时,OrderedDict就显得特别有用。例如,如果想在进行JSON编码时经穷控制各字段的顺序,那么只要首先在OrderedDict中构建数据就可以了。

>>> import json
>>> json.dumps(d)
'{“foo”: 1,”bar”:2,”spam”:3,”grok”:4}'


OrderedDict内部维护了一个双向链表,它会根据元素加入的顺序来排列键的位置。第一个新加入的元素被放置在链表的末尾。接下来对已存在的键做重新赋值不会改变键的顺序。

请注意OrderedDict的大小是普通字典的2倍多,这是由于它额外创建的链表所致。因此,如果打算构建一个涉及大量OrderedDict实例的数据结构(例如从CSV文件中读取100000行内容到OrderedDict列表中),那么需要认真对应用做需求分析,从而判断使用OrderedDict所带来的好处是否能超过因额外的内存开销所带来的缺点。

在两个字典中寻找相同点

考虑如下两个字典:

>>> a = {'x':1,'y':2,'z':3}
>>> b = {'w':10,'x':11,'y':2}


要找出这两个字典中的相同之处,只需要通过keys()或者items()方法执行常见的集合操作即可。例如:

>>> a.keys() & b.keys() # Find keys in common
{'x','y'}
>>> a.keys() - b.keys() #Find keys in a that are not in b
{'z'}
>>> a.items() & b.items()   #Find (key,value) pairs in common
{('y',2)}


这些类似的操作也可用来修改或过滤掉字典中的内容。例如,假设想创建一个新的字典,其中会去掉某些键。下面是使用了字典推导式的代码示例:

# make a new dictionary with certain keys removed
>>> c = {key:a[key] for key in a.keys() - {'z','w'}}
# c is {'x':1,'y':2}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: