你的分享就是我们的动力 ---﹥

Python 字典

时间:2013-01-31 10:40来源:www.chengxuyuans.com 点击:

描述

字典作为python的一种数据存储结构, 有着重要的意义,在诸如网络间数据传递(json),持久化存储(key-value)等方面,有着更深入的应用, 如此宽广的应用范畴,更需要我们从最基础, 最核心的层面上深入认识。

字典由Key-Value形式的数据构成,是无序的, 其中key是其索引部分,称为“键”, value是其值部分,称为“值”, 用list的概念可以这样理解之。 一个典型的字典是这样构成的: dict1 = {'key':'value'} 向字典添加一个键的同时,必须为该键增添一个值。 Python 的字典为通过键获取值进行了优化,但反过来并不是:

  1. Python的字典使用hash来散列存储,获取字典的信息,并不是通过遍历操作来实现的, 而是通过计算hash值,直接获取物理地址来获取值;
  2. Key更像是一个物理地址的别名,在序列中,索引更像是其逻辑地址,物理地址必须经过逻辑地址换算得到,和字典是有区别的。

下面是字典的一些常用操作:

创建字典

创建字典非常简单。其语法与集合的类似,但应当指定键值对而不是值。有了字典后,可以通过键来查找值。
跳过该代码清单
>>> a_dict = {'server': 'www.csvt.net', 'database': 'mysql'} ①
>>> a_dict
{'server': 'www.csvt.net', 'database': 'mysql'}
>>> a_dict['server'] ②
'www.csvt.net'
>>> a_dict['database'] ③
'mysql'
>>> a_dict['www.csvt.net'] ④
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'www.csvt.net'

①首先,通过将两个字典项指定给 a_dict 变量创建了一个新字典。每个字典项都是一组键值对,整个字典项集合都被大括号包裹在内。②'server' 为键,通过 a_dict['server'] 引用的关联值为 'www.csvt.net' 。③'database' 为键,通过 a_dict['database'] 引用的关联值为 'mysql' 。④可以通过键获取值,但不能通过值获取键。因此 a_dict['server'] 为 'www.csvt.net',而 a_dict['www.csvt.net'] 会引发例外,因为 'www.csvt.net' 并不是键。

修改字典

字典没有预定义的大小限制。可以随时向字典中添加新的键值对,或者修改现有键所关联的值。继续前面的例子:
跳过该代码清单
>>> a_dict
{'server': 'www.csvt.net', 'database': 'mysql'}
>>> a_dict['database'] = 'blog' ①
>>> a_dict
{'server': 'www.csvt.net', 'database': 'blog'}
>>> a_dict['user'] = 'mark' ②
>>> a_dict ③
{'server': 'www.csvt.net', 'user': 'mark', 'database': 'blog'}
>>> a_dict['user'] = 'dora' ④
>>> a_dict
{'server': 'www.csvt.net', 'user': 'dora', 'database': 'blog'}
>>> a_dict['User'] = 'mark' ⑤
>>> a_dict
{'User': 'mark', 'server': 'www.csvt.net', 'user': 'dora', 'database': 'blog'}

①在字典中不允许有重复的键。对现有的键赋值将会覆盖旧值。②可随时添加新的键值对。该语法与修改现有值相同。③新字典项(键为 'user',值为 'mark')出现在中间。事实上,在第一个例子中字典项按顺序出现是个巧合;现在它们不按顺序出现同样也是个巧合。④对既有字典键进行赋值只会用新值替代旧值。⑤该操作会将 user 键的值改回 "mark" 吗?不会!仔细看看该键——有个大写的 U 出现在 "User" 中。字典键是区分大小写的,因此该语句创建了一组新的键值对,而不是覆盖既有的字典项。对你来说它们可能是一样的,但对于 Python 而言它们是完全不同的。

混合值字典

字典并非只能用于字符串。字典的值可以是任何数据类型,包括整数、布尔值、任何对象,甚至是其它的字典。而且就算在同一字典中,所有的值也无须是同 一类型,您可根据需要混合匹配。字典的键要严格得多,可以是字符串、整数和其它一些类型。在同一字典中也可混合、匹配使用不同数据类型的键。
让我们在交互式 shell 中剖析一下:
跳过该代码清单
>>> SUFFIXES = {1000: ['KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
... 1024: ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']}
>>> len(SUFFIXES) ①
2
>>> 1000 in SUFFIXES ②
True
>>> SUFFIXES[1000] ③
['KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
>>> SUFFIXES[1024] ④
['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']
>>> SUFFIXES[1000][3] ⑤
'TB'

①类似列表和集合,len() 函数将返回字典中键的数量。②而且像列表和集合一样,可使用 in 运算符以测试某个特定的键是否在字典中。③1000 是 字典 SUFFIXES 的一个键;其值为一个 8 元素列表(确切地说,是 8 个字符串)。④同样, 1024 是字典 SUFFIXES 的键;其值也是一个 8 元素列表。⑤由于 SUFFIXES[1000] 是列表,可以通过它们的 0 基点索引来获取列表中的单个元素。

字典的其他问题

一. 字典的排序
引子:字典,形如 dic = {'a':1 , 'b':2 , 'c': 3},字典中的元素没有顺序,所以dic[0]是有语法错误的。并且不可以有重复的键值,所以 dic.add['c'] = 4后,字典变成 {'a':1 , 'b':2 , 'c': 4}.
现思考如下:如何根据需要可以根据“键”或“键值”进行不同顺序的排序?
函数原型:sorted(dic,value,reverse)
解释:dic为比较函数,value 为排序的对象(这里指键或键值),
reverse:注明升序还是降序,True--降序,False--升序(默认)
案例:dic = {'a':1 , 'b':2 , 'c': 3}
1.print sorted(dic.iteritems(), key = lambda asd:asd[0] ,reverse = True)
#结果:[('c', 3), ('b', 2), ('a', 1)]
2.print sorted(dic.iteritems(), key = lambda asd:asd[0] )
#结果:[('a', 1), ('b', 2), ('c', 3)] ,默认(升序)
3.print sorted(dic.iteritems(), key = lambda asd:asd[1] )
#结果:[('a', 1), ('b', 2), ('c', 3)]
这里介绍两个函数:
1.lambda
案例:fuc = lambda x:x+ 2
print fuc(3) #结果5,意思对于x ,返回 x + 2
2.iteritems()
案例:dic = {'a':1 , 'b':2 , 'c': 3}
print dic.iteritems() #<dictionary-itemiterator object at 0x01C247E0> 返回字典键-值对的一个迭代器
在函数sorted(dic.iteritems(), key = lambda asd:asd[1])中,第一个参数传给第二个参数“键-键值”,第二个参数取出其中的键(【0】)或键值(【1】)


二. Python字典列表和列表字典

data = []
dict = {'name':'Simon', 'age':20}
data.append(dict.copy())
dict = {'name':[], "age":0}
dict['name'].append('Simon')
这两种方式的不同和各自的适用范围:

最本质的区别:第一种方法得出的a是列表,而第二种的a是字典

用python语句表达来看就是:
1.type(a) == list
2.type(a) == dict
在交互式界面下显示:
第一种:
>>> a
[{'name':'fokil'}]
此时a是一个列表,他具有列表的一切方法和属性,但不具备任何字典的方法和属性。列表可以有N个元素,元素的类型是任意的,与列表本身无关。而此时的a有一个元素,该元素是一个字典——但这并不代表整个列表a带有任何字典的性质。明白?
第二种:
>>> a
{'name':['fokil']}
同上,此时a是一个字典,具有字典的一切方法和属性,但不具备任何列表的方法和属性。字典可以有N个元素,每个元素由一对key和内容的组合构成。key可以是任何单一对象的类型(不能是列表或字典——但可以是元组。当然,还可以是数字、字符/字符串,甚至是文件对象),而key对应的内容则可以是任意类型的。在此时,a中只有一个元素,key是一个字符串,而内容则是一个含有一个字符串元素的列表——同样,这不意味着a具有任何的列表性质
总而言之,严格的讲:没有“字典列表”或“列表字典”这种概念
只有一个列表,他包含的元素的类型是字典——当然,列表中的元素可以是不同类型的,譬如:
a = [1, 'test', [2,3,4], {'name':'fokil'}]
同理,只有一个字典,他包含的元素中的一部分是列表(当然,key部分不可能是列表)。当然,也有可能是不同类型的元素:
a = {1:'b',(1,2,3):[4,5,6],'test':{'test2':['test3']}}


3. 字典遍历的几种方法:
参考代码:
  1. #!/usr/bin/python
  2. dict={"a":"apple","b":"banana","o":"orange"}
  3. print "##########dict######################"
  4. for i in dict:
  5. print "dict[%s]=" % i,dict[i]
  6. print "###########items#####################"
  7. for (k,v) in dict.items():
  8. print "dict[%s]=" % k,v
  9. print "###########iteritems#################"
  10. for k,v in dict.iteritems():
  11. print "dict[%s]=" % k,v
  12. print "###########iterkeys,itervalues#######"
  13. for k,v in zip(dict.iterkeys(),dict.itervalues()):
  14. print "dict[%s]=" % k,v
其中:
  1. 第一种: 是in 操作, 返回key,
  2. 第二种: 是 k,v in操作, 返回 key, value
  3. 第三种: k,v in iteritems()函数操作, 返回key, value, 和前一种的区别是支持key排序
  4. 第四种: 取key的有序集,和value的有序集,返回key, value

转载注明地址:http://www.chengxuyuans.com/Python/48907.html

推荐文章