|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
给深度学习入门者的Python快速教程基础篇之 字典
3 G) e8 y" M H字典* [2 e$ e0 m* ^ L, w1 B
& v* B) l* R. O+ x- Y字典是一种非常常见的“键-值”(key-value)映射结构,键无重复,一个键不能对应多个值,不过多个键可以指向一个值。还是通过例子来了解,构建一个名字->年龄的字典,并执行一些常见操作:
! h1 X0 g1 i; h2 W0 @a = {'Tom': 8, 'Jerry': 7}$ q& s% p9 o8 p" [ t+ u
print(a['Tom']) # 8
* P# a$ R7 i b) Gb = dict(Tom=8, Jerry=7) # 一种字符串作为键更方便的初始化方式
" @' Q7 l* s: }2 Yprint(b['Tom']) # 86 g6 {! z) i: Y( ^
if 'Jerry' in a: # 判断'Jerry'是否在keys里面" q0 x0 ~4 Z, ?/ g$ X5 A
print(a['Jerry']) # 7! v$ d u3 e; z- r( `* }( @% @1 l) R
print(a.get('Spike')) # None,通过get获得值,即使键不存在也不会报异常
! e1 d; X: }. @2 g, W7 \" ja['Spike'] = 103 k& y) r5 r. l3 _) N- w- G& Q0 z
a['Tyke'] = 3
, V/ @; r7 G m5 v* Ra.update({'Tuffy': 2, 'Mammy Two Shoes': 42})! G: ]2 B4 d" p4 B& Q0 K- M
print(a.values()) # dict_values([8, 2, 3, 7, 10, 42])
5 i* W/ `8 H& _+ j: h4 xprint(a.pop('Mammy Two Shoes')) # 移除'Mammy Two Shoes'的键值对,并返回42
0 W+ `3 w& E; m/ q5 D% {5 {print(a.keys()) # dict_keys(['Tom', 'Tuffy', 'Tyke', 'Jerry', 'Spike'])/ |5 i; b# V& x) k# T! M% E1 g
( f; b s! _* t/ I* h, M: r
注意到初始化字典和集合很像,的确如此,集合就像是没有值只有键的字典。既然有了人名到年龄的映射,也许你立马想到是否可以给字典排序?在Python3.6之前,这个问题是错误的,字典是一种映射关系,没有顺序。当然了,如果要把(键, 值)的这种对进行排序,是没有问题的,前提是先把字典转化成可排序的结构,items()或者iteritems()可以做到这件事,接上段代码继续:, z- T) S+ L3 ?" Y( V- ?
b = a.items()
3 v' w; S& c; @print(b) # [('Tuffy', 2), ('Spike', 10), ('Tom', 8), ('Tyke', 3), ('Jerry', 7)]4 {# S1 r, X7 Q$ }8 w# N1 \& S- N
from operator import itemgetter
) d8 q/ {- ~' A) U: L' Wc = sorted(a.items(), key=itemgetter(1))
0 {+ H- G% V, v+ I; cprint(c) # [('Tuffy', 2), ('Tyke', 3), ('Jerry', 7), ('Tom', 8), ('Spike', 10)]
% [' e" ` C/ X. G: t# Cd = sorted(a.iteritems(), key=itemgetter(1))
% @# ?+ ~: m9 C: @; s' Jprint(d) # [('Tuffy', 2), ('Tyke', 3), ('Jerry', 7), ('Tom', 8), ('Spike', 10)]' \, h+ a. P* ~1 d+ h
e = sorted(a)
6 Q" M. e% m/ b5 E8 Oprint(e) # 只对键排序,['Jerry', 'Spike', 'Tom', 'Tuffy', 'Tyke']) }3 M9 y% z0 C5 p
0 ?8 {% H. a0 I& Zitems()可以把字典中的键值对转化成一个列表,其中每个元素是一个tuple,tuple的第一个元素是键,第二个元素是值。变量c是按照值排序,所以需要一个操作符itemgetter,去位置为1的元素作为排序参考,如果直接对字典排序,则其实相当于只是对键排序。字典被当作一个普通的可遍历结构使用时,都相当于遍历字典的键。如果觉得字典没有顺序不方便,可以考虑使用OrderedDict,使用方式如下:$ N8 D6 u- u( l
from collections import OrderedDict3 }, F* z: e1 l% [) R( _9 G
a = {1: 2, 3: 4, 5: 6, 7: 8, 9: 10}# ?! {+ Y! O1 a' `2 j; f
b = OrderedDict({1: 2, 3: 4, 5: 6, 7: 8, 9: 10})
' u5 Q( t; L5 ?7 Aprint(a) # {1: 2, 3: 4, 9: 10, 5: 6, 7: 8}
9 v7 Z3 q" V3 Q) u- ~9 _print(b) # OrderedDict([(1, 2), (3, 4), (9, 10), (5, 6), (7, 8)])
# o0 z+ y3 ]8 f5 z/ n2 z! @, M! F1 K+ D; R% Y) I
这样初始化时的顺序就保留了,除了有序的特性以外,用法上和字典没有区别。2016年9月,Guido宣布在Python3.6中,字典将默认有序,这样就不用纠结了。另外需要注意的一点是字典是通过哈希表实现的,所以键必须是可哈希的, list不能被哈希,所以也不能作为字典的键,而tuple就可以。! I. G6 O1 M# l! z' p
& S2 y- P/ `1 |" I8 }
因为上上段代码中用到了iteritems(),所以这里顺带提一下迭代器(iterator),迭代器相当于一个函数,每次调用都返回下一个元素,从遍历的角度来看就和列表没有区别了。iteritems()就是一个迭代器,所以效果一样,区别是迭代器占用更少内存,因为不需要一上来就生成整个列表。一般来说,如果只需要遍历一次,用迭代器是更好的选择,若是要多次频繁从一个可遍历结构中取值,且内存够,则直接生成整个列表会更好。当然,用迭代器生成一个完整列表并不麻烦,所以有个趋势是把迭代器作为默认的可遍历方式,比如前面我们使用过用来生成等差数列列表的range(),在Python2中对应的迭代器形式是xrange()。在Python3中,range()就不再产生一个列表了,而是作为迭代器,xrange()直接没了。 | 6 m1 ^3 j0 h8 t* z$ D" s- F! K M
|
|