# -*- encoding: utf-8 -*-
import bisect
import collections
import heapq
import random
'''
第46条: 使用内置算法与数据结构
关键:
1 双向队列
collections.deque: 可以从队列的头部或尾部插入或移除一个元素
消耗常数级别的时间
与list的区别:
list尾部插入是常数时间,但是头部插入/移除是线形级别时间
分析:
list应该是单链表的实现,维护了指向最后一个元素的指针
deque应该是双向链表,同时维护第一个元素和最后一个元素的指针
2 有序字典
标准字典: 无序,在相同键值对的字典上迭代,可能出现不同的
迭代顺序。
collections.OrderedDict:
含义: 特殊字典,按照插入顺序,保留键值对在字典中的顺序
适用: 对顺序有先后要求的场合,例如最长前缀匹配
3 带有默认值的字典
collections.defaultdict: 如果字典里面没有待访问的键,那么就会把
默认值与这个键关联起来。只需要提供返回默认值的函数
4 优先级队列
heap模块: 实现了优先级队列,提供heappush, heappop, nsmallest,
实现在list中创建堆结构
特点: 优先级上执行操作,消耗线性级别时间
5 二分查找
bisect模块: 提供bisect_left函数提供了二分查找算法
bisect_left函数返回索引表示待搜寻的值在序列中的插入点
6 与迭代器有关的工具
itertools模块: 组合操作迭代器
分为三大类:
1) 把迭代器连接起来的函数:
chain: 把多个迭代器按顺序连接成一个迭代器
cycle: 无限重复某个迭代器中的各个元素
tee: 把一个迭代器拆分成多个平行的迭代器
zip_longest: 与内置zip函数相似,但是可以对应长度不同的迭代器
2) 从迭代器中过滤元素的函数
islice: 在不进行复制的前提下,根据索引值来切割迭代器
takewhile: 在判定函数为True的时候,从迭代器中逐个返回元素
dropwhile: 从判定函数为False的地方开始,逐个返回迭代器中的元素
filterwhile: 从迭代器中逐个返回能令判定函数为False的所有元素,与filter函数功能相反
3) 从迭代器中过滤元素的函数:
product: 根据迭代器中元素计算笛卡尔积,并返回
permutations: 用迭代器中元素构建长度为N的有序排列,并将所有排列返回
combination: 用迭代器中的元素构建长度为N的各种无序组合并返回
参考:
Effectiv Python 编写高质量Python代码的59个有效方法
'''
def useDeque():
myQueue = collections.deque()
myQueue.append(1)
value = myQueue.popleft()
print value
def useDict():
a = {'foo': 1, "bar": 2}
while True:
z = random.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
result= a==b
print "Equal ?, {value}".format(value=result)
def useOrderedDict():
dict1 = collections.OrderedDict()
dict1['foo'] = 1
dict1['bar'] = 2
dict2 = collections.OrderedDict()
dict2['foo'] = 'red'
dict2['bar'] = 'blue'
for element1, element2 in zip(dict1.values(), dict2.values()):
print (element1, element2)
def useDefaultDict():
counter = collections.defaultdict(int)
counter['hello'] += 1
print counter['hello']
def useHeap():
arr = []
heapq.heappush(arr, 5)
heapq.heappush(arr, 3)
heapq.heappush(arr, 7)
heapq.heappush(arr, 4)
assert arr[0] == heapq.nsmallest(1, arr)[0] == 3
print heapq.heappop(arr)
print heapq.heappop(arr)
print heapq.heappop(arr)
print heapq.heappop(arr)
def useBisect():
arr = list(range(10**6))
index = bisect.bisect_left(arr, 991234)
print index
def process():
useDeque()
useDict()
useOrderedDict()
useDefaultDict()
useHeap()
useBisect()
if __name__ == "__main__":
process()