前言
python内置的数据结构包括:列表(list)、集合(set)、字典(dictionary),一般情况下我们可以直接使用这些数据结构,但通常我们还需要考虑比如搜索、排序、排列以及赛选等一些常见的问题。
如何巧妙的使用数据结构和同数据有关的算法,在collections模块中包含了针对各种数据结构的解决方法。
1、序列分解为变量
In [5]: a = (4,5,6)
In [6]: x,y,z = a
In [7]: x
Out[7]: 4
In [8]: z
Out[8]: 6
In [9]: y
Out[9]: 5
In [10]: b = ['python',222,(2018,9,30)] #嵌套分解变量
In [11]: p,n,(year,mon,day) = b
In [12]: p
Out[12]: 'python'
In [13]: n
Out[13]: 222
In [14]: year
Out[14]: 2018
In [15]: day
Out[15]: 30
可以分解的对象只要是可迭代对象如字符串、文件、迭代器和生成器
In [16]: s = 'py'
In [17]: x,y = s
In [18]: x
Out[18]: 'p'
忽略某个值使用下划线代替
In [19]: data = 'python'
In [20]: x,_,_,y,_,_ = data
In [21]: x
Out[21]: 'p'
In [22]: y
Out[22]: 'h'
2、任意长度对象分解元素
要从某个可迭代对象中分解出N个元素,可以使用python的“*表达式”来代表多个
列1:在作业成绩中去掉最高和最低后取平均分
In [47]: grades = (68,98,85,78,84,79,88)
In [48]: def drop_first_last(grades):
...: first,*middle,last = grades
...: return sum(middle) / len(middle)
...:
...:
In [49]: drop_first_last(sorted(list(grades),reverse=True))
Out[49]: 82.8
列2:在嵌套元组中*式语法的分解应用
records = [
('foo',1,2,3),
('bar',11,22,33),
('foo',4,5,6),
('bar',44,55,66),
]
def do_foo(x,y,z):
print('foo',x,y,z)
def do_bar(a,b,c):
print('bar',a,b,c)
for tag,*args in records: #分解元组打印
if tag == 'foo':
do_foo(*args)
elif tag == 'bar':
do_bar(*args)
#outing
foo 1 2 3
bar 11 22 33
foo 4 5 6
bar 44 55 66
列3:通过split拆分分解元素
In [52]: passwd = 'root:x:0:0:root:/root:/bin/bash'
In [53]: username,*_,homedir,sh = passwd.split(":")
In [54]: username
Out[54]: 'root'
In [55]: homedir
Out[55]: '/root'
In [56]: sh
Out[56]: '/bin/bash'
3、保存最后N个元素
列1:使用collections.deque保存有限的历史纪录,deque用来创建一个固定长度的队列
In [61]: from collections import deque
#创建队列长度对象
In [62]: q = deque(maxlen=3)
加入数据到队列
In [63]: q.append(1)
In [64]: q.append(2)
In [65]: q.append(3)
In [66]: q
Out[66]: deque([1, 2, 3])
In [67]: q.append(4)
In [68]: q
Out[68]: deque([2, 3, 4])
从左边加入数据到队列
In [69]: q.appendleft(5)
In [70]: q
Out[70]: deque([5, 2, 3])
从末尾取出一个数据
In [71]: q.pop()
Out[71]: 3
In [72]: q
Out[72]: deque([5, 2])
In [73]: q.popleft()
Out[73]: 5
In [74]: q
Out[74]: deque([2])
4、找到最大或最小的N个元素
在heapq模块中有两个函数nlargest()从最大的值开始取,nsmallest()从最小的值开始取
In [75]: import heapq
In [76]: numbers = [1,3,4,9,11,34,55,232,445,9812,321,45,67,434,555]
#取三个最大的值
In [77]: heapq.nlargest(3,numbers)
Out[77]: [9812, 555, 445]
#取三个最小的值
In [78]: heapq.nsmallest(3,numbers)
Out[78]: [1, 3, 4]
5、python堆排序peapq模块
hepaq模块实现了python中的推排序,并提供了很多方法,让用python实现排序算法有了简单快捷的方式
In [1]: import heapq
In [2]: date = [19,1,9,3,11,21]
In [3]: heap = []
heappush方法会插入一个元素到堆中,并按从小到大排序
In [4]: for i in date:
...: heapq.heappush(heap,i)
...:
In [5]: heap
Out[5]: [1, 3, 9, 19, 11, 21]
In [6]: date
Out[6]: [19, 1, 9, 3, 11, 21]
heapify方法会重新排序整个列表
In [7]: heapq.heapify(date)
In [8]: date
Out[8]: [1, 3, 9, 19, 11, 21]
heappop()方法会取出第一个元素,并将剩下的元素堆排序
In [10]: date
Out[10]: [19, 1, 9, 3, 11, 21]
In [11]: heapq.heappop(date)
Out[11]: 19
In [12]: date
Out[12]: [1, 3, 9, 21, 11]
heapreplace()的作用是在堆中取第一个元素并插入一个元素
In [27]: date = [11,8,3,78,35]
In [28]: heapq.heapreplace(date,1)
Out[28]: 11
In [29]: date
Out[29]: [1, 8, 3, 78, 35]
在集合中找出最大或者最小的N个元素,可以使用nlargest()和nsmallest()
In [30]: date = [3,88,32,97,56]
In [31]: heapq.nlargest(2,date)
Out[31]: [97, 88]
In [33]: heapq.nsmallest(2,date)
Out