使用内置数据结构和算法 python
当你实现很是小的的Python程序时,你可能会看到由你的代码的算法复杂性而形成的减速。 这个一般不是Python语言自己速度的形成,这更有多是由于没有为您的问题使用最好的算法和数据结构。幸运的是Python标准库有许多内置的算法和数据结构能够使用。除了速度,使用这些经常使用的算法和数据结构可让你的生活更轻松。 你可能想使用的一些更有力的工具,这是一个棘手的问题。 避免从新实现经常使用功能将会节省您的时间。算法
Double-ended Queue(双端队列)
deque类是在collections模块中,它是一个double-ended队列。从deque队列开始或者结尾,插入或者删除会花费相同的时间。这个使其成为先进先出(FIFO)队列的理想选择。数据结构
fifo = deque() fifo.append(1) # Producer x = fifo.popleft() # Consumer
内置List也能够实现有序队列,如fifo。但内置List从列表头部的插入或删除项,花费时间是线性的,这比常数慢得多。app
Ordered Dictionary(有序字典)
标准字典是无序的。 这意味着具备相同的键和值的dict能够有不一样的迭代次序。 这种行为有一个使人惊讶的副产品就是实现字典的快速哈希表。dom
a = {} a['foo'] = 1 a['bar'] = 2 # Randomly populate ‘b’ to cause hash conflicts while True: z = randint(99, 1013) b = {} for i in range(z): b[i] = i b['foo'] = 1 b['bar'] = 2 for i in range(z): del b[i] if str(b) != str(a): break print(a) print(b) print('Equal?', a == b) >>> {'foo': 1, 'bar': 2} {'bar': 2, 'foo': 1} Equal? True
collections模块中的OrderedDict类是一种特殊类型的字典,它跟踪其键的插入顺序。 迭代键OrderedDict具备可预测的行为。 这能够大大简化测试和调试经过使全部代码肯定性。数据结构和算法
a = OrderedDict() a['foo'] = 1 a['bar'] = 2 b = OrderedDict() b['foo'] = 'red' b['bar'] = 'blue' for value1, value2 in zip(a.values(), b.values()): print(value1, value2) >>> 1 red 2 blue
Default Dictionary
字典对记帐和跟踪统计很是有用。内建的字典类型是不能假设任何键已经存在。 这使得它作一些简单的事情时显得笨拙,如增长一个存储在字典中的计数器。函数
stats = {} key = 'my_counter' if key not in stats: stats[key] = 0 stats[key] += 1
collections模块中的defaultdict类简化了当key不存在时自动存储默认值。 全部你须要作的是提供每次键丢失时将返回默认值的函数。 在这里例如,int内置函数返回0如今,递增计数器是
简单。int()->0工具
stats = defaultdict(int) stats['my_counter'] += 1
Heap Queue
关于这里,heap这种数据结构的介绍有一个简单的blog能够去看一下http://blog.csdn.net/minxihou/article/details/51857518
堆是用于维护优先级队列的有用数据结构。 heapq模块提供了在标准list类型中建立堆的功能使用函数heappush,heappop和nsmallest等函数。任何优先级的项能够按任何顺序插入堆中。测试
a = [] heappush(a, 5) heappush(a, 3) heappush(a, 7) heappush(a, 4)
老是先移除最高优先级(lowest number)的项..net
print(heappop(a), heappop(a), heappop(a), heappop(a)) >>> 3 4 5 7
生成的list在heapq以外很容易使用。 访问堆的0索引将老是返回最小的项。
a = [] heappush(a, 5) heappush(a, 3) heappush(a, 7) heappush(a, 4) assert a[0] == nsmallest(1, a)[0] == 3
list的sort方法保持不变。
print('Before:', a) a.sort() print('After:' , a) >>> Before: [3, 4, 7, 5] After: [3, 4, 5, 7]
Bisection
调用index方法查找列表中的项须要花费与list长度成线性比例的时间。
x = list(range(10**6)) i = x.index(991234)
使用bisect模块的方法,如:bisect_left,是使用二分查找的方法。它返回的索引是插入点值插入序列。
i = bisect_left(x, 991234)
二分搜索的复杂度是对数的。 这意味着使用bisect搜索100万个项的list的速度是使用线性索引方式搜索的14倍。It’s way faster!
Iterator Tools
tertools内置模块包含大量有用与迭代器相关的函数。不是全部这些都在Python 2中可用,但它们能够轻松地使用经过查看模块中记录的simple recipes。 请参阅help(itertools)得到更多详细信息。
itertools中的函数主要分为三类:
Linking iterators together
•chain:将多个迭代器组合成一个顺序迭代器。
•cycle:一直重复迭代器的项。
•tee:将单个迭代器拆分为多个并行迭代器。
•zip_longest:内置zip函数的变体,当迭代的几个对象长度不一样的时候有更好的表现。
Filtering items from an iterator
•islice:经过数字索引切片迭代器,而不进行复制。
•takewhile:当断言函数返回Ture时返回迭代器中的项。
•dropwhile:当断言函数第一次为False时,返回迭代器中的项。
•filterfalse:当断言函数第一次为False时,返回迭代器中全部的项。 与内置函数filter做用相反。
Combinations of items from iterators(组合迭代器中的项)
•product:返回迭代器中项的笛卡尔乘积,是一种很好的替代深层嵌套列表推导的方法。
•permutations:返回长度为N的有序排列迭代器。
•combination:返回长度为N的,用迭代器中未重复项所组成的无序组合。
在itertools模块中有更多的功能和recipes可用不能在这里一一说起。 每当你发现本身处理一些棘手的迭代代码,itertools文档是值得再次查看,看看是否有你想要的东西。
Things to Remember
一、使用Python的内置模块用于算法和数据结构。
二、不要本身从新实现此功能。