python数据结构
2017-08-21 09:53
148 查看
本文译自https://docs.python.org/2.7/tutorial/。完全是出于个人兴趣翻译的,请勿追究责任。另外,谢绝商业牟利。刊印请与本人和原作者联系,无授权不得刊印,违者必究其责任。如需转发,请注明来源,并保留此行,尊重本人的劳动成果,谢谢。
来源:CSDN博客
作者:奔跑的QQEE
python 版本:2.7.13
(本文有删改)
例:
或许你已注意到像 insert,remove,sort 这类方法仅仅是修改了列表而并没有输出返回值。其实并非没有返回值,而是返回了默认值,None 。
python专门设计了快速在表两端追加删除元素的方法,从而实现了队列。只需调用collections.deque 即可。例:
filter(function,sequence)方法接收一个目标函数和原始序列作参数;结果返回一个使function 函数为真的,包含于原始序列的子序列。如果原始序列是 str,unicode或tuple类型,那么子序列也是这种类型;否则子序列总是list 类型。例:
map(function,sequence)方法为原始序列中每一项都调用一次function函数,并将所有子返回值整理成一个列表返回。例:
若function函数需要多个参数,那么map方法需要传递多个原始序列。例:
再看一个错误的例子:
因为sep序列长度为7,seq序列长度为8 。因此seq[7] 将与None类型数据计算。而 ‘+’ 运算符无法用于int 类型数据与None类型数据的计算。所以出现类型错误。
reduce(function,sequence)方法先将原始序列中的前两个项一起计算,将结果返回。随后再将结果与下一个项一起计算,将结果返回。直到原始序列中无项为止。例:
如果目标序列仅有一项,那么reduce() 的计算结果便是此值;如果目标序列是空,那么将抛出异常。
reduce()方法也可传递三个参数。其中第三个参数表示起始值。如果目标序列是空便返回起始值。目标函数首先应用于起始值和序列中的第一个值;然后应用于上一步的结果和下一个序列值。例:
python内置函数已经提供了求和方法,sum( sequence )。
用此方法(递推列表)创建列表,可以包含若干 for 语句或 if 语句。例:
这相当于:
再看个综合例子:
递推列表还可包含更加复杂的表达式和内置函数。
有一列表如下:
下例将颠倒行列:
这相当于:
或
或使用内置的zip() 函数,也能得到相同的效果。
del 也可用于删除变量:例:
如上所示,python支持元组序列。
元组由一系列逗号隔开的值构成。输出的结果总以括号包括,但输入时可不加括号。例:
元组和列表相似,但用处不同。元组元素不可变,且可包含不同的序列元素。而列表元素可变。
空元组和仅有一个元素的元组有特殊的表达方式,如:
语句
用括号或set() 方法可以创建集合。
注意:如要创建空集合,应当使用set() 方法,而不应使用{} 括号。因为后者创建空字典。
例:
python 除了支持递推列表外,也支持递推集合。例:
序列是通过一系列数字进行索引操作的,而字典则通过键。任何不可变的类型都可当键。如,字符串,数字,元组(当元组只包含字符串,数字或元组时才可当键;若直接或间接包含了可变的对象,则不能当键。例如,列表就不能当键。因为列表可被修改)。
字典是键值对的集合。 所以字典中键值是唯一的。创建空字典用{}。向 {} 内添加多个用逗号隔开的 键:值 来增加字典元素;这也是字典元素输出的形式。
字典的基本操作是用键存值和给键查值。可用 del 语句删除某键值对。如果用已存在的键存对应的值,那么已存在的旧值将被覆盖。如果用不存在的键查值将出现错误提示。
keys() 方法返回包含所有字典中的键的无序列表。若要使结果有序,使用 sorted() 方法就行了。若要检测某键是否在字典中,使用关键字 in 。例:
dict() 方法直接将键值对序列构造成字典。例:
相当于
用递推的方式创建字典也是可以的。例:
同时循环多个序列时,可通过zip() 方法将多个实体元素配对。例:
反向循环某序列时,首先应指定序列的方向,然后再调用 reversed() 方法。例:
按序循环某序列,应使用sorted() 方法。此方法将返回一新的序列且不改变原序列。例:
循环字典时,调用iteritems() 方法可同时返回键值对。例:
偶尔在循环列表的同时需要直接对列表修改。然而,并不推荐这样做。更简单,更安全的做法是使用一新的空列表代替直接修改原列表。例:
比较运算符 in 和 not in 检测序列中是否有某值。 is 和 is not 比较两个对象是否是相同的。所有的比较运算符都有相同的优先级,其优先级都比所有的数字运算符低。
可连做比较运算。例:
比较运算也可结合布尔运算符
布尔运算符
来源:CSDN博客
作者:奔跑的QQEE
python 版本:2.7.13
(本文有删改)
python 数据结构
一、列表
列表结构有一些方法。如下所示:方法 | 作用 |
---|---|
list.append(x) | 在列表尾追加新项,相当于 a[len(a):]=[x] |
list.extend(L) | 用给定的列表扩展另一个列表。相当于a[len(a):]=L |
list.insert(i,x) | 在给定位置插入项。i 表示要插入的位置。如 a.insert(0,x)表示将x插入到列表的第一个位置,此时x为第一项。a.insert(len(a),x) 相当于 a.append(x) |
list.remove(x) | 移除列表中值为x的项。若没有此项返回错误。 |
list.pop([i]) | 移除列表中指定位置的项,例a.pop(0)。若不指定索引值,例a.pop() 将移除并返回列表中最后一项。(方括号表示此项是可选的) |
list.index(x) | 返回第一个值为x的项的索引值。若无此项,则返回错误。 |
list.count(x) | 返回x出现的次数 |
list.sort() | 对列表排序 |
list.reverse() | 逆置列表元素 |
>>> a = [66.25, 333, 333, 1, 1234.5] >>> print a.count(333), a.count(66.25), a.count('x') 2 1 0 >>> a.insert(2, -1) >>> a.append(333) >>> a [66.25, 333, -1, 333, 1, 1234.5, 333] >>> a.index(333) 1 >>> a.remove(333) >>> a [66.25, -1, 333, 1, 1234.5, 333] >>> a.reverse() >>> a [333, 1234.5, 1, 333, -1, 66.25] >>> a.sort() >>> a [-1, 1, 66.25, 333, 333, 1234.5] >>> a.pop() 1234.5 >>> a [-1, 1, 66.25, 333, 333]
或许你已注意到像 insert,remove,sort 这类方法仅仅是修改了列表而并没有输出返回值。其实并非没有返回值,而是返回了默认值,None 。
二、将列表用作栈
栈的特点是“先进后出”。利用列表定义的方法,很容易实现栈的特性。例:>>> stack = [3, 4, 5] >>> stack.append(6) >>> stack.append(7) >>> stack [3, 4, 5, 6, 7] >>> stack.pop() 7 >>> stack [3, 4, 5, 6] >>> stack.pop() 6 >>> stack.pop() 5 >>> stack [3, 4]
三、将列表用作队列
队列的特点是“先进先出”。但是,用list定义的方法实现队列特性并不像实现栈的特性一样简单。原因是在表尾追加删除元素很快速,而在表头插入或删除元素很慢(其它所有元素都需要重新调整位置)。python专门设计了快速在表两端追加删除元素的方法,从而实现了队列。只需调用collections.deque 即可。例:
>>> from collections import deque >>> queue = deque(["Eric", "John", "Michael"]) >>> queue.append("Terry") # 尾部追加元素 Terry >>> queue.append("Graham") # 尾部追加元素 Graham >>> queue.popleft() # 移除并返回左侧元素 'Eric' >>> queue.popleft() # 移除并返回左侧元素 'John' >>> queue deque(['Michael', 'Terry', 'Graham'])
四、三个常用的函数
有三个常用的函数经常和列表配合使用。它们是 filter(),map(),reduce()。filter(function,sequence)方法接收一个目标函数和原始序列作参数;结果返回一个使function 函数为真的,包含于原始序列的子序列。如果原始序列是 str,unicode或tuple类型,那么子序列也是这种类型;否则子序列总是list 类型。例:
>>> def f(x): return x % 3 == 0 or x % 5 == 0 # x除以3或5后结果为0就是真 ... >>> filter(f, range(2, 25)) # 返回[2,25)范围内能满足f为真的序列 [3, 5, 6, 9, 10, 12, 15, 18, 20, 21, 24]
map(function,sequence)方法为原始序列中每一项都调用一次function函数,并将所有子返回值整理成一个列表返回。例:
>>> def cube(x): return x*x*x ... >>> map(cube, range(1, 11)) [1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]
若function函数需要多个参数,那么map方法需要传递多个原始序列。例:
>>> seq = range(8) >>> def add(x, y): return x+y ... >>> map(add, seq, seq) [0, 2, 4, 6, 8, 10, 12, 14]
再看一个错误的例子:
>>>seq=range(8) >>>sep=range(7) >>>def add(x,y):return x+y ... >>>map(add,seq,sep) Trackback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 2, in add TypeError: unsupported operand type(s) for +: 'int' and 'NoneType'
因为sep序列长度为7,seq序列长度为8 。因此seq[7] 将与None类型数据计算。而 ‘+’ 运算符无法用于int 类型数据与None类型数据的计算。所以出现类型错误。
reduce(function,sequence)方法先将原始序列中的前两个项一起计算,将结果返回。随后再将结果与下一个项一起计算,将结果返回。直到原始序列中无项为止。例:
>>> def add(x,y): return x+y ... >>> reduce(add, range(1, 11)) 55
如果目标序列仅有一项,那么reduce() 的计算结果便是此值;如果目标序列是空,那么将抛出异常。
reduce()方法也可传递三个参数。其中第三个参数表示起始值。如果目标序列是空便返回起始值。目标函数首先应用于起始值和序列中的第一个值;然后应用于上一步的结果和下一个序列值。例:
>>> def sum(seq): ... def add(x,y): return x+y ... return reduce(add, seq, 0) ... >>> sum(range(1, 11)) 55 >>> sum([]) 0
python内置函数已经提供了求和方法,sum( sequence )。
五、递推列表
使用递推列表可以简洁地来创建列表。列表中的每个元素都满足一定的规律。例:>>> squares = [] >>> for x in range(10): ... squares.append(x**2) ... >>> squares [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] # 一般方法得到的列表 >>>ListSquares = [x**2 for x in range(10)] >>>ListSquares [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] # 递推列表方法得到的列表 >>>NewSquares = map(lambda x: x**2, range(10)) >>>NewSquares [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] # map 方法得到的列表
用此方法(递推列表)创建列表,可以包含若干 for 语句或 if 语句。例:
>>> [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y] [(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
这相当于:
>>> combs = [] >>> for x in [1,2,3]: ... for y in [3,1,4]: ... if x != y: ... combs.append((x, y)) ... >>> combs [(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
再看个综合例子:
>>> vec = [-4, -2, 0, 2, 4] >>> # 以 vec 列表元素的 2 倍构造新列表 >>> [x*2 for x in vec] [-8, -4, 0, 4, 8] >>> # 去除 vec 列表中的负数 >>> [x for x in vec if x >= 0] [0, 2, 4] >>> # vec 列表中的每个元素都执行 abs(x)函数,以求其绝对值。 >>> [abs(x) for x in vec] [4, 2, 0, 2, 4] >>> # freshfruit 列表中每个元素都执行 strip()方法,以去除多余空格。 >>> freshfruit = [' banana', ' loganberry ', 'passion fruit '] >>> [weapon.strip() for weapon in freshfruit] ['banana', 'loganberry', 'passion fruit'] >>> # 创建形如 (number, square) 的二维元组 >>> [(x, x**2) for x in range(6)] [(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25)] >>> # 元组必须用括号括起来,否则会抛出语法错误 >>> [x, x**2 for x in range(6)] File "<stdin>", line 1, in <module> [x, x**2 for x in range(6)] ^ SyntaxError: invalid syntax >>> # 用两个 for 创建列表 >>> vec = [[1,2,3], [4,5,6], [7,8,9]] >>> [num for elem in vec for num in elem] [1, 2, 3, 4, 5, 6, 7, 8, 9]
递推列表还可包含更加复杂的表达式和内置函数。
六、嵌套的递推列表
递推列表还可以包含递推列表。有一列表如下:
>>> matrix = [ ... [1, 2, 3, 4], ... [5, 6, 7, 8], ... [9, 10, 11, 12], ... ]
下例将颠倒行列:
>>> [[row[i] for row in matrix] for i in range(4)] [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
这相当于:
>>> transposed = [] >>> for i in range(4): ... transposed.append([row[i] for row in matrix]) ... >>> transposed [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
或
>>> transposed = [] >>> for i in range(4): ... transposed_row = [] ... for row in matrix: ... transposed_row.append(row[i]) ... transposed.append(transposed_row) ... >>> transposed [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
或使用内置的zip() 函数,也能得到相同的效果。
>>> zip(*matrix) [(1, 5, 9), (2, 6, 10), (3, 7, 11), (4, 8, 12)]
七、del语句
del 语句可通过指定索引值或索引范围来删除列表中的项。例:>>> a = [-1, 1, 66.25, 333, 333, 1234.5] >>> del a[0] >>> a [1, 66.25, 333, 333, 1234.5] >>> del a[2:4] >>> a [1, 66.25, 1234.5] >>> del a[:] >>> a []
del 也可用于删除变量:例:
>>> a = [-1, 1, 66.25, 333, 333, 1234.5] >>> del a >>> a Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'a' is not defined # 未定义名称 a
八、元组和序列
列表和字符串有许多相同的特性,如它们都支持索引和切片操作;它们是两种不同的序列(字符串,unicode字符,列表,元组,二进制数组,buffer 和 xrange)。如上所示,python支持元组序列。
元组由一系列逗号隔开的值构成。输出的结果总以括号包括,但输入时可不加括号。例:
>>> t = 12345, 54321, 'hello!' >>> t[0] 12345 >>> t (12345, 54321, 'hello!') >>> # 元组也可被嵌套 ... u = t, (1, 2, 3, 4, 5) >>> u ((12345, 54321, 'hello!'), (1, 2, 3, 4, 5)) >>> # 元组元素是不可被修改的 ... t[0] = 88888 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'tuple' object does not support item assignment
元组和列表相似,但用处不同。元组元素不可变,且可包含不同的序列元素。而列表元素可变。
空元组和仅有一个元素的元组有特殊的表达方式,如:
>>> empty = () >>> singleton = 'hello', # 一个元素的元组(值后跟一逗号) >>> len(empty) 0 >>> len(singleton) 1 >>> singleton ('hello',)
语句
t = 12345, 54321, 'hello!'是元组打包的例子。三个元素被打包成一个元组元素 t。另外,解包也是可以的。例:
>>> x, y, z = t # 将 元组 t 解包,各个元素值依次赋给 x,y,z
九、集合
python支持集合操作。集合是无序的且无重复元素的。集合的基本操作包括关系检测,清除重复元素。另外,集合还支持并,交,差,对称差的数学运算。用括号或set() 方法可以创建集合。
注意:如要创建空集合,应当使用set() 方法,而不应使用{} 括号。因为后者创建空字典。
例:
>>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana'] >>> fruit = set(basket) # 创建一无重复元素的集合 >>> fruit set(['orange', 'pear', 'apple', 'banana']) >>> 'orange' in fruit # 关系检测,'orange'是否在fruit集合内 True >>> 'crabgrass' in fruit False >>> # 挑出非重复元素分别赋给 a,b ... >>> a = set('abracadabra') >>> b = set('alacazam') >>> a # 集合 a set(['a', 'r', 'b', 'c', 'd']) >>> a - b # 在 a 中而不在 b 中的元素 set(['r', 'd', 'b']) >>> a | b # 在 a 中或在 b 中的元素 set(['a', 'c', 'r', 'd', 'b', 'm', 'z', 'l']) >>> a & b # 在 a 中且在 b 中的元素 set(['a', 'c']) >>> a ^ b # 公共元素外的元素 set(['r', 'd', 'b', 'm', 'z', 'l'])
python 除了支持递推列表外,也支持递推集合。例:
>>> a = {x for x in 'abracadabra' if x not in 'abc'} >>> a set(['r', 'd'])
十、字典
python 支持字典类型。字典在其它语言中又被称作关联内存,或关联数组。序列是通过一系列数字进行索引操作的,而字典则通过键。任何不可变的类型都可当键。如,字符串,数字,元组(当元组只包含字符串,数字或元组时才可当键;若直接或间接包含了可变的对象,则不能当键。例如,列表就不能当键。因为列表可被修改)。
字典是键值对的集合。 所以字典中键值是唯一的。创建空字典用{}。向 {} 内添加多个用逗号隔开的 键:值 来增加字典元素;这也是字典元素输出的形式。
字典的基本操作是用键存值和给键查值。可用 del 语句删除某键值对。如果用已存在的键存对应的值,那么已存在的旧值将被覆盖。如果用不存在的键查值将出现错误提示。
keys() 方法返回包含所有字典中的键的无序列表。若要使结果有序,使用 sorted() 方法就行了。若要检测某键是否在字典中,使用关键字 in 。例:
>>> tel = {'jack': 4098, 'sape': 4139} >>> tel['guido'] = 4127 >>> tel {'sape': 4139, 'guido': 4127, 'jack': 4098} >>> tel['jack'] 4098 >>> del tel['sape'] >>> tel['irv'] = 4127 >>> tel {'guido': 4127, 'irv': 4127, 'jack': 4098} >>> tel.keys() ['guido', 'irv', 'jack'] >>> 'guido' in tel True
dict() 方法直接将键值对序列构造成字典。例:
>>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)]) {'sape': 4139, 'jack': 4098, 'guido': 4127}
相当于
>>> dict(sape=4139, guido=4127, jack=4098) {'sape': 4139, 'jack': 4098, 'guido': 4127}
用递推的方式创建字典也是可以的。例:
>>> {x: x**2 for x in (2, 4, 6)} {2: 4, 4: 16, 6: 36}
十一、循环技术
使用enumerate() 方法,可在循环某个序列的同时检出索引和其对应的值。例:>>> for i, v in enumerate(['tic', 'tac', 'toe']): ... print i, v ... 0 tic 1 tac 2 toe
同时循环多个序列时,可通过zip() 方法将多个实体元素配对。例:
>>> questions = ['name', 'quest', 'favorite color'] >>> answers = ['lancelot', 'the holy grail', 'blue'] >>> for q, a in zip(questions, answers): ... print 'What is your {0}? It is {1}.'.format(q, a) ... What is your name? It is lancelot. What is your quest? It is the holy grail. What is your favorite color? It is blue.
反向循环某序列时,首先应指定序列的方向,然后再调用 reversed() 方法。例:
>>> for i in reversed(xrange(1,10,2)): ... print i ... 9 7 5 3 1
按序循环某序列,应使用sorted() 方法。此方法将返回一新的序列且不改变原序列。例:
>>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana'] >>> for f in sorted(set(basket)): ... print f ... apple banana orange pear
循环字典时,调用iteritems() 方法可同时返回键值对。例:
>>> knights = {'gallahad': 'the pure', 'robin': 'the brave'} >>> for k, v in knights.iteritems(): ... print k, v ... gallahad the pure robin the brave
偶尔在循环列表的同时需要直接对列表修改。然而,并不推荐这样做。更简单,更安全的做法是使用一新的空列表代替直接修改原列表。例:
>>> import math >>> raw_data = [56.2, float('NaN'), 51.7, 55.3, 52.5, float('NaN'), 47.8] >>> filtered_data = [] >>> for value in raw_data: ... if not math.isnan(value): ... filtered_data.append(value) ... >>> filtered_data [56.2, 51.7, 55.3, 52.5, 47.8]
十二、条件
while 和 if 语句可包含任何,而不仅仅是比较运算符。比较运算符 in 和 not in 检测序列中是否有某值。 is 和 is not 比较两个对象是否是相同的。所有的比较运算符都有相同的优先级,其优先级都比所有的数字运算符低。
可连做比较运算。例:
a < b == c表示检测 a 是否比 b 小,b 又是否等于 c 。
比较运算也可结合布尔运算符
and或
or进行。比较的结果或是其它布尔表达式都可用
not修饰。布尔运算符比比较运算符的优先级更低。在布尔运算符之间,
not的优先级最高,
or的优先级最低。所以
A and not B or C相当于
(A and (not B)) or C。
布尔运算符
and和
or也叫作短路运算符。从左到右依次计算各参数的运算结果。只要结果确定就停止计算。例,如果
A和
c是true,
B是false,
A and B and C将不和
C式计算。若将布尔运算符用于非布尔运算,计算的结果将是最后一个参与了计算的参数的值。例:
>>> string1, string2, string3 = '', 'Trondheim', 'Hammer Dance' >>> non_null = string1 or string2 or string3 >>> non_null 'Trondheim' # string1 和 string2 运算后得到了结果,因此不再和 string3 一起运算
十三、序列比较
序列对象可与同类型的序列作比较。比较方法是字典排序:首先前两项作比较,若这两项一样,则比较接下来的两项,直到某个序列无项可比。若待比两项是相同的序列类型,则递归执行字典排序。如果两序列所有项都相同,那么这两个序列就相等;如果某序列是另一序列的子序列,那么该序列比另一序列小,反之则大。对字符串的字典排序是从左到右依次比较各个字符的 ASCII 码值,码值大的字符串大于码值小的。例:(1, 2, 3) < (1, 2, 4) [1, 2, 3] < [1, 2, 4] 'ABC' < 'C' < 'Pascal' < 'Python' (1, 2, 3, 4) < (1, 2, 4) (1, 2) < (1, 2, -1) (1, 2, 3) == (1.0, 2.0, 3.0) (1, 2, ('aa', 'ab')) < (1, 2, ('abc', 'a'), 4)
相关文章推荐
- Python常见数据结构整理
- 第四节 python数据结构
- Python常用数据结构描述
- 零基础自学用Python 3开发网络爬虫(二): 用到的数据结构简介以及爬虫Ver1.0 alpha
- 基础数据结构:栈、队列——Python实现
- python学习(一)常见的数据结构
- Python数据结构与算法之字典树实现方法示例
- python数据结构-序列\序列通用操作\列表(基本操作、方法)
- Python数据结构之图与二叉查找树
- Python数据结构--单链表
- (原创)数据结构---队栈操作(Python)
- Python数据结构学习之旋转链表详解
- python数据结构之链表
- Python实现基本数据结构---队列操作
- python基础系列教程——数据结构(列表、元组、字典、集合、链表)
- Python数据结构之链表
- Python培训知识总结系列- 第二章Python数据结构第一部分,列表与for循环
- Python数据结构的实现
- 基本数据结构(算法导论)与python
- Python 的数据结构——序列讲解(附实例代码)