列表 list 与字典 dictionary,是两个最为常用的数据类型之一了,几乎在每一个 python 的脚本上面都可以看到他们的身影,他们的特点是可以被原地修改,增加,缩减,与嵌套,是一个处理复杂讯息结构的好工具!
在我刚入门的时候,光是看到上面提到的特点也体会不到这两个工具的强大之处,直到自己亲手写代码的时候,才自然而然的明白了这个道理。讯息结构之所以复杂原因就在于它很大一笔,很多属性,需要被个别挑出运算,定期还需要更新,最后查询的速度还不能慢,而这两个工具恰好一次满足了所有的需求。
[ 列表 list ]
它可以含纳任意形态的数字,字符串,与其他形态资料,甚至再包含一层 list 都没有问题,是个有顺序性的可变排列,能够在原地被修改,当分片 slicing 或合并操作的时候,用新的列表元素去覆盖旧的列表元素完成操作。
Python 解释器认定其为“数组结构”,把所有的数据按顺序依次储存,而非“链表结构”(其特征是物理储存上的非连续,非顺序的储存结构,如后面介绍的元组 tuple 就是此类)。读取速度上与 C 语言的数组读取速度差不多,并且当我们把一个变量赋予一个数据结构变量名时,python 是储存对象的“引用”,而非直接拷贝对象。
在列表的内置方法中,很多方法和上一节处理字符串的方法是一样的,但是还是那句老话:相同属性的数据才能够彼此做运算符的处理,切记!
平时最为常见的使用方法有如下几项:
>>> L1 = ['a', 'b', 'c']
>>> L2 = [1, 2, 3, [3, 2, 1]]
>>> L2[i]
2
>>> L2[3][1]
2
>>> L2[0:2]
[1, 2]
>>> len(L2)
4
>>> L1 + L2
['a', 'b', 'c', 1, 2, 3, [3, 2, 1]]
>>> L1 * 2
['a', 'b', 'c', 'a', 'b', 'c']
>>> L3 = [x +'z' for x in L1]
['az', 'bz', 'cz']
>>> 3 in L2
True
>>> L1.append('d')
['a', 'b', 'c', 'd']
>>> L1.extend('abc')
['a', 'b', 'c', 'a', 'b', 'c']
>>> L1.extend(['abc'])
['a', 'b', 'c', 'abc']
>>> L2.index(2)
3
>>> L2.insert(2, 8)
[1, 2, 8, 3, [3, 2, 1]]
>>> del L2[1]
[1, 3, [3, 2, 1]]
备注:以上举例只是简单表示结果,用上方法后,还需要进一步呼叫该变量才会有结果出来。这里只是方便起见,并不是实际打印情况。
下面链接提供更为详细的列表内置函数功能:
o http://www.runoob.com/python/python-lists.html
特殊的情况:sort() and sorted() 的介绍:
o https://www.cnblogs.com/zuizui1204/p/6422939.html
有两点特殊的使用过成需要注意,如果遇到这个情况:
>>> L = [1, 2, 3]
>>> X = L * 2
>>> Y = [L] * 2
>>> X
[1, 2, 3, 1, 2, 3]
>>> Y
[[1, 2, 3], [1, 2, 3]]
如果今天 L 突然改变了内容,那么只有 Y 的内容会跟着发生联动,只要保持着原本 L 原汁原味的样貌,那么就 list 本身的可修改性就会沿着继承的事实遗传下来,需要特别注意!
>>> L = ['mail']
>>> L.append(L)
>>> L
['mail', [...]]
另一个情况是如果遇到自己把自己本身 append 上去了,就会出现一个这玩意儿,表示 python 错乱了,[...] 是一个 Nonetype。
{ 字典 Dictionary }
除了 list 之外,dictionary 可以算是最 Flexible 的内置数据结构类型了。不过差别在于它是一个没有顺序之分的集合,全部东西都是搅和在一起的,虽然受还是可以靠 len() 来找出一共有几个元素,但是它们彼此就是不排序。提取的办法靠的是“键”来搜寻,键的角色如同搜索关键字一样,是个非常实用,并且速度非常快的工具。例如下面范例:
>>> D = {'spam':2, 'eggs':3}
>>> D['spam']
2
字典又可以被称为“关联数组”(associative array)或是哈希表(hash)。
需要插入新值的时候,必须确定的是“:”的两边是否都已经有指定对应的数据与键的名字,如下范例:
>>> D['jam'] = ['grill, 'bake', 'fry']
>>> D
{'spam':2, 'eggs':3, 'jam':['grill', 'bake', 'fry']
>>> D.items()
[('spam', 2), ('eggs', 3), ('jam', ['grill', 'bake', 'fry'])]
>>> D.values()
[2, 3, ['grill', 'bake', 'fry']]
>>> D.get('eggs')
3
相对 list 而言,字典不用额外的 append 这类辅助,因为它本身就没有顺序可言,一坨东西加上一个东西,还是一坨东西,而这坨东西理论上可以无节制的一直被增多,数据就像是他的食物,他就是一个大胃王!只是记得事前给他吃的每一样东西都要打上出处,像是食物必须表上保质期一样,不然就要报错啦。
下面链接提供更为详细的列表内置函数功能:
o http://www.runoob.com/python/python-dictionary.html
避免 missing key(键)的错误
当读取的键不存在时,可以试着填入默认值,让 python 不报错,程序得以继续运行,有 if... else 方法,也有 try... except 方法,甚至可以用 .get() 直接为没有值的部分添加默认值,如下面范例:
>>> if Matrix.has_key((2, 3, 4)):
print(Matrix[(2, 3, 4)])
>>> else:
print(0)
--------------------------------------------------------------
>>> try:
print(Matrix[(2, 3, 4)])
>>> except KeyError:
print(0)
--------------------------------------------------------------
>>> Matrix.get((2, 3, 4), 0) # mind that...
# if the key and the corresponding value does exist, this value won't be replaced
字典接口
为了更有效率的去储存于检索字典里面的元素,some extended modules are also really helpful for this purpose. such as:
>>> import anydbm
>>> file = anydbm.open('filename') # link to a file
>>> file['key'] = 'data' # store data by key
>>> data = file['key'] # fetch data by key
抑或,把 anydbm 换成 shelve 的方法可以被用来储存整个Python 的对象,其中 CGI 脚本支持的一个接口业余字典类似,使用 cgi.FieldStorage 这个类操控数据的话,也会产生一个类似字典的对象,如下:
>>> import cgi
>>> form = cgi.FieldStorage() # parse form data here
>>> if form.has_key('name')
showReply('hello, ' + form['name'].value)
下次开始正式介绍元组 Tuple,与如何用 python 打开电脑里面的文件,it's helpful for u~