Python数据结构详细
1. 关于列表更多的内容Python 的列表数据类型包含更多的方法。这里是所有的列表对象方法list.append(x)把一个元素添加到列表的结尾相当于a[len(a):] [x]list.extend(L)将一个给定列表中的所有元素都添加到另一个列表中相当于a[len(a):] L。list.insert(i, x)在指定位置插入一个元素。第一个参数是准备插入到其前面的那个元素的索引例如a.insert(0, x)会插入到整个列表之前而a.insert(len(a), x)相当于a.append(x)。list.remove(x)删除列表中值为 x 的第一个元素。如果没有这样的元素就会返回一个错误。list.pop([i])从列表的指定位置删除元素并将其返回。如果没有指定索引a.pop() 返回最后一个元素。元素随即从列表中被删除方法中 i 两边的方括号表示这个参数是可选的而不是要求你输入一对方括号你会经常在Python 库参考手册中遇到这样的标记。list.clear()从列表中删除所有元素。相当于del a[:]list.index(x)返回列表中第一个值为 x 的元素的索引。如果没有匹配的元素就会返回一个错误。list.count(x)返回 x 在列表中出现的次数。list.sort()对列表中的元素就地进行排序。list.reverse()就地倒排列表中的元素。list.copy()返回列表的一个浅拷贝。等同于a[:]。下面这个示例演示了列表的大部分方法:12345678910111213141516171819202122 a[66.25,333,333,1,1234.5]print(a.count(333), a.count(66.25), a.count(x))210 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]也许大家会发现像insertremove或者sort这些修改列表的方法没有打印返回值–它们返回None。 [1] 在 python 中对所有可变的数据类型这是统一的设计原则。1.1. 把列表当作堆栈使用列表方法使得列表可以很方便的做为一个堆栈来使用堆栈作为特定的数据结构最先进入的元素最后一个被释放后进先出。用append()方法可以把一个元素添加到堆栈顶。用不指定索引的pop()方法可以把一个元素从堆栈顶释放出来。例如:123456789101112131415 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]1.2. 把列表当作队列使用你也可以把列表当做队列使用队列作为特定的数据结构最先进入的元素最先释放先进先出。不过列表这样用效率不高。相对来说从列表末尾添加和弹出很快在头部插入和弹出很慢因为为了一个元素要移动整个列表中的所有元素。要实现队列使用collections.deque它为在首尾两端快速插入和删除而设计。例如:12345678910fromcollectionsimportdeque queuedeque([Eric,John,Michael]) queue.append(Terry)# Terry arrives queue.append(Graham)# Graham arrives queue.popleft()# The first to arrive now leavesEric queue.popleft()# The second to arrive now leavesJohn queue# Remaining queue in order of arrivaldeque([Michael,Terry,Graham])1.3. 列表推导式列表推导式为从序列中创建列表提供了一个简单的方法。普通的应用程式通过将一些操作应用于序列的每个成员并通过返回的元素创建列表或者通过满足特定条件的元素创建子序列。例如, 假设我们创建一个squares列表,可以像下面方式:123456 squares[]forxinrange(10):... squares.append(x**2)... squares[0,1,4,9,16,25,36,49,64,81]注意这个 for 循环中的被创建(或被重写)的名为 x 的变量在循环完毕后依然存在。使用如下方法我们可以计算squares的值而不会产生任何的副作用:1squareslist(map(lambdax: x**2,range(10)))或者等价于:1squares[x**2forxinrange(10)]上面这个方法更加简明且易读.列表推导式由包含一个表达式的括号组成表达式后面跟随一个for子句之后可以有零或多个for或if子句。结果是一个列表由表达式依据其后面的for和if子句上下文计算而来的结果构成。例如如下的列表推导式结合两个列表的元素如果元素之间不相等的话:12 [(x, y)forxin[1,2,3]foryin[3,1,4]ifx !y][(1,3), (1,4), (2,3), (2,1), (2,4), (3,1), (3,4)]等同于:12345678 combs[]forxin[1,2,3]:...foryin[3,1,4]:...ifx !y:... combs.append((x, y))... combs[(1,3), (1,4), (2,3), (2,1), (2,4), (3,1), (3,4)]值得注意的是在上面两个方法中的 for 和 if 语句的顺序。如果想要得到一个元组例如上面例子中的 (x, y)必须要加上括号:123456789101112131415161718192021222324252627 vec[-4,-2,0,2,4]# create a new list with the values doubled [x*2forxinvec][-8,-4,0,4,8]# filter the list to exclude negative numbers [xforxinvecifx 0][0,2,4]# apply a function to all the elements [abs(x)forxinvec][4,2,0,2,4]# call a method on each element freshfruit[ banana, loganberry ,passion fruit ] [weapon.strip()forweaponinfreshfruit][banana,loganberry,passion fruit]# create a list of 2-tuples like (number, square) [(x, x**2)forxinrange(6)][(0,0), (1,1), (2,4), (3,9), (4,16), (5,25)]# the tuple must be parenthesized, otherwise an error is raised [x, x**2forxinrange(6)]Filestdin, line1,in?[x, x**2forxinrange(6)]^SyntaxError: invalid syntax# flatten a list using a listcomp with two for vec[[1,2,3], [4,5,6], [7,8,9]] [numforeleminvecfornuminelem][1,2,3,4,5,6,7,8,9]列表推导式可使用复杂的表达式和嵌套函数:123frommathimportpi [str(round(pi, i))foriinrange(1,6)][3.1,3.14,3.142,3.1416,3.14159]1.4. 嵌套的列表推导式列表解析中的第一个表达式可以是任何表达式包括列表解析。考虑下面由三个长度为 4 的列表组成的 3x4 矩阵:12345 matrix[... [1,2,3,4],... [5,6,7,8],... [9,10,11,12],... ]现在如果你想交换行和列可以用嵌套的列表推导式:12 [[row[i]forrowinmatrix]foriinrange(4)][[1,5,9], [2,6,10], [3,7,11], [4,8,12]]像前面看到的嵌套的列表推导式是对 for 后面的内容进行求值所以上例就等价于:123456 transposed[]foriinrange(4):... transposed.append([row[i]forrowinmatrix])... transposed[[1,5,9], [2,6,10], [3,7,11], [4,8,12]]反过来说如下也是一样的:12345678910 transposed[]foriinrange(4):...# the following 3 lines implement the nested listcomp... transposed_row[]...forrowinmatrix:... transposed_row.append(row[i])... transposed.append(transposed_row)... transposed[[1,5,9], [2,6,10], [3,7,11], [4,8,12]]在实际中你应该更喜欢使用内置函数组成复杂流程语句。对此种情况 zip() 函数将会做的更好:12list(zip(*matrix))[(1,5,9), (2,6,10), (3,7,11), (4,8,12)]更多关于本行中使用的星号的说明参考 参数列表的分拆。2. del 语句有个方法可以从列表中按给定的索引而不是值来删除一个子项del语句。它不同于有返回值的pop()方法。语句del还可以从列表中删除切片或清空整个列表我们以前介绍过一个方法是将空列表赋值给列表的切片。例如:12345678910 a[-1,1,66.25,333,333,1234.5]dela[0] a[1,66.25,333,333,1234.5]dela[2:4] a[1,66.25,1234.5]dela[:] a[]del 也可以删除整个变量:1dela此后再引用命名 a 会引发错误直到另一个值赋给它为止。我们在后面的内容中可以看到del的其它用法。3. 元组和序列我们知道列表和字符串有很多通用的属性例如索引和切割操作。它们是 序列 类型参见Sequence Types — list, tuple,range中的两种。因为Python是一个在不停进化的语言也可能会加入其它的序列类型这里介绍另一种标准序列类型 元组 。