5 Python常用数据结构
Table of Contents
- 1 List
- 1.1 List 的使用
- 1.2 将List当作栈(Stack)
- 1.3 将List当作队列
- 1.4 函数式程序设计工具
- 1.5 List Comprehensions
- 2 del 语句
- 3 Tuples 和 序列
- 4 Sets
- 5 Dictionaries
- 6 循环技术
- 7 更多的条件操作
- 8 比较序列操作
1 List
1.1 List 的使用
- List 相关函数:append,extend,insert,remove,pop,index,count,sort,reverse
>>> a [3, 1, 2] >>> b [4, 7, 6, 10] >>> a.append(5) >>> a [3, 1, 2, 5] >>> a.extend(b) >>> a [3, 1, 2, 5, 4, 7, 6, 10] >>> a.insert(0,9) >>> a [9, 3, 1, 2, 5, 4, 7, 6, 10] >>> a.insert(1,8) >>> a [9, 8, 3, 1, 2, 5, 4, 7, 6, 10] >>> a.insert(5,1) >>> a [9, 8, 3, 1, 2, 1, 5, 4, 7, 6, 10] >>> a.remove(1) >>> a [9, 8, 3, 2, 1, 5, 4, 7, 6, 10] >>> a.pop(0) 9 >>> a [8, 3, 2, 1, 5, 4, 7, 6, 10] >>> a.pop() 10 >>> a [8, 3, 2, 1, 5, 4, 7, 6] >>> a.index(1) 3 >>> a.insert(2,6) >>> a [8, 3, 6, 2, 1, 5, 4, 7, 6] >>> a.count(3) 1 >>> a.count(6) 2 >>> a.sort() >>> a [1, 2, 3, 4, 5, 6, 6, 7, 8] >>> a.reverse() >>> a [8, 7, 6, 6, 5, 4, 3, 2, 1] >>>
1.2 将List当作栈(Stack)
使用上面将的 append, pop 函数很容易将List当作栈来使用。栈有先进后出的特点。
>>> stack = [5,2,8] >>> stack.append(9) >>> stack [5, 2, 8, 9] >>> stack.append(1) >>> stack [5, 2, 8, 9, 1] >>> stack.pop() 1 >>> stack [5, 2, 8, 9] >>> stack.pop() 9 >>> stack [5, 2, 8]
1.3 将List当作队列
List同样很容易当作队列来使用,队列的特点是先进先出。然而,这样使用效率非常低。因为在队列头部删除元素时, 所有后面的元素都要左移。 可以使用collections.deque来实现队列,它是专门用于队列的,其设计保证了入队和出队的效率。
>>> from collections import deque >>> queue = deque(["Linux","Unix","Windows"]) >>> queue deque(['Linux', 'Unix', 'Windows']) >>> queue.append("Mac") >>> queue deque(['Linux', 'Unix', 'Windows', 'Mac']) >>> queue.popleft() 'Linux' >>> queue deque(['Unix', 'Windows', 'Mac'])
1.4 函数式程序设计工具
对于List来说,有三个函数是非常有用的:filter,map,reduce
- filter(function,sequence) 从序列中选出能使函数function返回真的元素
>>> def f(x): return x % 2 !=0 and x % 3 != 0 ... >>> filter(f, range(1,20)) [1, 5, 7, 11, 13, 17, 19]
- map(function,sequence) 将函数function作用到sequence上的每一个元素,返回对应的值
>>> def f(x): return x*2+1 ... >>> map(f,range(1,10)) [3, 5, 7, 9, 11, 13, 15, 17, 19]
如果函数有两个参数,那么需要两个序列
>>> def f(x,y): return x + y ... >>> map(f,[1,5,2],[6,3,9]) [7, 8, 11]
- reduce(function,sequence) 将二元函数function作用在sequence前两个元素上,再将结果和下一个元素共同作为函数参数
>>> def f (x,y): return x + y ... >>> reduce(f,[1,2,3,4]) 10 >>> def f(x,y): return x*y ... >>> reduce(f,[1,2,3,4]) 24
1.5 List Comprehensions
List Comprehensions 是创建List的一种方式,例如
>>> squares = [x**2 for x in [4,3,7]] >>> squares [16, 9, 49] >>> [(x,y) for x in [1,2,3] for y in [3,2,4] if x != y] [(1, 3), (1, 2), (1, 4), (2, 3), (2, 4), (3, 2), (3, 4)]
这种方式有时候可以避免写很多代码,而且清晰可读,和数学里定义集合的方式很像,haskell中也有这样的方式。 另外,这货还可以嵌套着玩儿
>>> matrix = [ ... [1,2,3,4], ... [5,6,7], ... [8,9,10,11,12] ... ] >>> matrix [[1, 2, 3, 4], [5, 6, 7], [8, 9, 10, 11, 12]] >>> [ [row[i] for row in matrix] for i in range(3) ] [[1, 5, 8], [2, 6, 9], [3, 7, 10]]
当然,这只是体现List Comprehensions的特性,真玩的时候,我们还有更方便的:
>>> zip(*matrix)
[(1, 5, 8), (2, 6, 9), (3, 7, 10)]
2 del 语句
>>> a = [5,2,67,1,72,1,728] >>> a [5, 2, 67, 1, 72, 1, 728] >>> del a[0] >>> a [2, 67, 1, 72, 1, 728] >>> del a[1:3] >>> a [2, 72, 1, 728] >>> del a[:] >>> a [] >>> del a >>> a Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'a' is not defined
3 Tuples 和 序列
表示序列的,还有一种标准的数据结构,Tuples。 Tuple中的元素是不能修改的。 虽然Tuple和List看起来很像,但是他们用于不同的场合,后面我们会介绍。
>>> t = "linux", "unix", "winx" >>> t ('linux', 'unix', 'winx') >>> p = ("ubuntu","arch","freebsd") >>> p ('ubuntu', 'arch', 'freebsd') >>> t[0] 'linux' >>> t[0] = "*nix" Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'tuple' object does not support item assignment >>> s = [1,2,3] >>> s [1, 2, 3] >>> s[0] = 9 >>> s [9, 2, 3]
Tuple 有packing 和 unpacking 两个概念 packing 就是:
>>> t = "linux","unix","freebsd"
unpacking 就是:
>>> x, y, z = t >>> x 'linux' >>> y 'unix' >>> z 'freebsd'
4 Sets
python还有一种数据结构,Sets。用于存放不重复元素的无序集合,常用于成员测试,消除重复项等。Sets支持 数学集合中的交,差,并,等操作。
>>> os = ['linux','windows7','freebsd'] >>> oset = set(os) >>> oset set(['windows7', 'freebsd', 'linux']) >>> 'linux' in oset True >>> 'unix' in oset False >>> a = set('sdkf;ahdf') >>> b = set('safj13325er') >>> a - b # 在 a 不在 b set(['h', 'k', 'd', ';']) >>> a | b # 在 a 或在 b set(['r', 'a', 'e', 'd', 'f', 'h', 'k', 'j', '3', '1', 's', '2', '5', ';']) >>> a & b # 在 a 且在 b set(['a', 's', 'f']) >>> a ^ b # 在 a 或在 b 且不同时在a,b set(['e', 'd', 'h', 'k', 'j', '1', '3', '2', '5', ';', 'r'])
集合也支持 comprehensions 特性
>>> a = {x for x in 'abcde' if x not in 'abe'} >>> a set(['c', 'd'])
但是,必须要注意,定义一个sets时不能用{},而要用set()
5 Dictionaries
Python中另一个有用的数据结构是Dictionary。它由key:value两部分组成,通过key值可以查找到value,key值是惟一的。
>>> tel = {'jack':123, 'lucy':456} >>> tel['lucy'] 456 >>> tel {'jack': 123, 'lucy': 456} >>> tel['lily'] = 789 >>> tel {'lily': 789, 'jack': 123, 'lucy': 456} >>> tel.keys() ['lily', 'jack', 'lucy'] >>> 'lily' in tel True
使用dict可以由(key,value)组成的序列直接构造dictionary. 使用comprehension的方式也可以构造dictionary.
>>> dict( [('linux',123),('unix',456)] ) {'unix': 456, 'linux': 123} >>> dict(linux=826, unix=910) {'unix': 910, 'linux': 826} >>> {x: x*2+1 for x in (3,7,1)} {1: 3, 3: 7, 7: 15}
6 循环技术
当我们想遍历一个序列时,可以使用 下标,值,enumerate() 来完成
>>> for i, v in enumerate(['linux', 'unix', 'winx']): ... print i, v ... 0 linux 1 unix 2 winx
当我们想遍历两个及以上序列时,可以用 zip() 来完成
>>> ask = ['name', 'system', 'editor'] >>> answer = ['Steve', 'Mac', 'emacs'] >>> for q, a in zip(ask, answer): ... print 'What is your {0}? It is {1}.'.format(q,a) ... What is your name? It is Steve. What is your system? It is Mac. What is your editor? It is emacs.
如果想逆序遍历,可以用 reversed() 来完成
>>> for i in reversed(['winx', 'unix', 'linux']): ... print i ... linux unix winx
如果想排序后再遍历,可以用 sorted() 来完成
>>> for i in sorted( ['unix', 'linux', 'winx'] ): ... print i ... linux unix winx
如果想遍历一个dictionary,可以用iteritems()来完成
>>> system = { 'unix':'second', 'linux':'first', 'winx':'last' } >>> for key,value in system.iteritems(): ... print key, value ... unix second winx last linux first
7 更多的条件操作
对于 while 和 if 而言,条件操作不仅仅是比较,还有更多可用操作。 in 和 not in 可以判断一个元素是否在一个序列中 is 和 not is 可以判断两个对象是不是指的是同一个对象 比较操作可以链接起来,例如 a < b == c , 表示 a < b 且 b == c 还有著名Bool操作: and, or, not ,它们可以配合比较操作 Bool操作优先级低于比较操作,其中not优先级最高,or最低
8 比较序列操作
序列对象也可以比较,它们是按照 字典序(lexicographical ordering) 的顺序比较
>>> (1,2,3) < (1,2,4) True >>> (1,2,3,4) < (1,2,3) False >>> (1,2,3,-1) < (1,2,3) False >>> (1,2,3) == (1.0,2.0,3.0) True