字典
字典可能是Python最为重要的数据结构。它更为常⻅的名字是哈希映射或关联数组。它是键值对的⼤⼩可变集合,键和值都是Python对象。创建字典的⽅法之⼀是使⽤尖括号,⽤冒号分隔键和值:
In[101]:empty_dict={}
In[102]:d1={'a':'somevalue','b':[1,2,3,4]}
In[103]:d1
Out[103]:{'a':'somevalue','b':[1,2,3,4]}
你可以像访问列表或元组中的元素⼀样,访问、插⼊或设定字典
中的元素:
In[104]:d1[7]='aninteger'
In[105]:d1
Out[105]:{'a':'somevalue','b':[1,2,3,4],7:'aninteger'}
In[106]:d1['b']
Out[106]:[1,2,3,4]
你可以⽤检查列表和元组是否包含某个值得⽅法,检查字典中是否包含某个键:
In[107]:'b' in d1
Out[107]:True
可以⽤del关键字或pop⽅法(返回值得同时删除键)删除值:
In[108]:d1[5]='somevalue'
In[109]:d1
Out[109]:
{'a':'somevalue','b':[1,2,3,4],7:'aninteger',5:'somevalue'}
In[110]:d1['dummy']='anothervalue'
In[111]:d1
Out[111]:
{'a':'somevalue','b':[1,2,3,4],7:'aninteger',
5:'somevalue','dummy':'anothervalue'}
In[112]:del d1[5]
In[113]:d1
Out[113]:
{'a':'somevalue','b'[1,2,3,4],7:'aninteger','dummy':'anothervalue'}
In[114]:ret=d1.pop('dummy')
In[115]:ret
Out[115]:'anothervalue'
In[116]:d1
Out[116]:{'a':'somevalue','b':[1,2,3,4],7:'anintege'}
删除元素使用del[key],pop[key],表示删除字典中特定的键值对。
keys和values是字典的键和值的迭代器⽅法。虽然键值对没有
顺序,这两个⽅法可以⽤相同的顺序输出键和值:
In[117]:list(d1.keys())
Out[117]:['a','b',7]
In[118]:list(d1.values())
Out[118]:['somevalue',[1,2,3,4],'aninteger']
⽤update⽅法可以将⼀个字典与另⼀个融合:
In[119]:d1.update({'b':'foo','c':12})
In[120]:d1
Out[120]:{'a':'somevalue','b':'foo',7:'aninteger','c':12}
update如果原字典有的键值对出现在融合的字典时则进行覆盖,如果没有则添加。update⽅法是原地改变字典,因此任何传递给update的键的键的值都会被舍弃。
⽤序列创建字典
常常,你可能想将两个序列配对组合成字典。下⾯是⼀种写法:
mapping={}
for key,value in zip(key_list,value_list):
mapping[key]=value
因为字典本质上是2元元组的集合,dict可以接受2元元组的列
表:
In[121]:mapping=dict(zip(range(5),reversed(range(5))))
In[122]:mapping
Out[122]:{0:4,1:3,2:2,3:1,4:0}
后⾯会谈到dict comprehensions,另⼀种构建字典的优雅⽅式。
默认值
下⾯的逻辑很常⻅:
if key in some_dict:
value=some_dict[key]
else:
value=default_value
因此,dict的⽅法get和pop可以取默认值进⾏返回,上⾯的if-else语句可以简写成下⾯:
value=some_dict.get(key,default_value)
get默认会返回None,如果不存在键,pop会抛出⼀个例外。关于设定值,常⻅的情况是在字典的值是属于其它集合,如列表。
例如,你可以通过⾸字⺟,将⼀个列表中的单词分类:
In[123]:words=['apple','bat','bar','atom','book']
In[124]:by_letter={}
In[125]:for word in words:
.....:letter=word[0]
.....:if letter not in by_letter:
.....:by_letter[letter]=[word]
.....:else:
.....:by_letter[letter].append(word)
.....:
In[126]:by_letter
Out[126]:{'a':['apple','atom'],'b':['bat','bar','book']}
setdefault⽅法就正是⼲这个的。前⾯的for循环可以改写为:
for word in words:
letter=word[0]
by_letter.set default(letter,[]).append(word)
collections模块有⼀个很有⽤的类,defaultdict,它可以进
⼀步简化上⾯。传递类型或函数以⽣成每个位置的默认值:
from collections import default dict
by_letter=default dict(list)
for word in words:
by_letter[word[0]].append(word)
有效的键类型字典的值可以是任意Python对象,⽽键通常是不可变的标量类
(整数、浮点型、字符串)或元组(元组中的对象必须是不可变
的)。这被称为“可哈希性”。可以⽤hash函数检测⼀个对象是否
是可哈希的(可被⽤作字典的键):
In[127]:hash('string')
Out[127]:5023931463650008331
In[128]:hash((1,2,(2,3)))
Out[128]:1097636502276347782
In[129]:hash((1,2,[2,3]))#failsbecauselistsaremutable
---------------------------------------------------------------------------
TypeErrorTraceback(mostrecentcalllast)
<ipython-input-129-800cd14ba8be>in<module>()
---->1hash((1,2,[2,3]))#failsbecauselistsaremutable
TypeError:unhashabletype:'list'
要⽤列表当做键,⼀种⽅法是将列表转化为元组,只要内部元素
可以被哈希,它也就可以被哈希:
In[130]:d={}
In[131]:d[tuple([1,2,3])]=5
In[132]:d
Out[132]:{(1,2,3):5}