# heapq模块(堆排序):从列表中找出最大的或最小的N个元素 import heapq list1 = [34, 25, 12, 99, 87, 63, 58, 78, 88, 92] list2 = [ {'name': 'IBM', 'shares': 100, 'price': 91.1}, {'name': 'AAPL', 'shares': 50, 'price': 543.22}, {'name': 'FB', 'shares': 200, 'price': 21.09}, ] print(heapq.nlargest(3, list1)) # nsmallest print(heapq.nlargest(2, list2, key=lambda x: x['price'])) ################################################################################################ import itertools itertools.permutations('ABCD') # 产生ABCD的全排列 itertools.combinations('ABCDE', 3) # 产生ABCDE的五选三组合 itertools.product('ABCD', '123') # 产生ABCD和123的笛卡尔积 itertools.cycle(('A', 'B', 'C')) # 产生ABC的无限循环序列 # collections模块常用的工具类: # namedtuple:命令元组,它是一个类工厂,接受类型的名称和属性列表来创建一个类。 # deque:双端队列,是列表的替代实现。Python中列表底层是基于数组来实现的,而deque底层是双向链表,因此当你需要在头尾添加和删除元素是,deque会表现出更好的性能,渐近时间复杂度为O(1)。 # Counter:dict子类,键是元素,值是元素的计数,它的most_common()方法获取出现频率最高的元素。Counter和dict的继承关系值得商榷的,按照CARP原则,Counter跟dict的关系应该设计为关联关系更为合理。 # OrderedDict:dict的子类,它记录键值对插入的顺序,看起来既有字典的行为,也有链表的行为。 # defaultdict:类似于字典类型,但是可通过默认的工厂函数来获得键对应的默认值,相比字典中的setdefault()方法,这种做法更加高效。 from collections import Counter words = [ 'look', 'into', 'my', 'eyes','the', 'eyes', "don't", 'look', 'around', 'the', 'eyes', 'look', 'into', 'my', 'eyes', "you're", 'under' ] counter = Counter(words) print(counter.most_common(3)) # 找出序列中出现次数最多的元素
数据结构和算法
-
算法:解决问题的方法和步骤
-
评价算法的好坏:渐近时间复杂度和渐近空间复杂度。
-
渐近时间复杂度的大O标记:
常用算法:
- 穷举法 - 又称为暴力破解法,对所有的可能性进行验证,直到找到正确答案。
- 贪婪法 - 在对问题求解时,总是做出在当前看来
- 最好的选择,不追求最优解,快速找到满意解。
- 分治法 - 把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题,直到可以直接求解的程度,最后将子问题的解进行合并得到原问题的解。
- 回溯法 - 回溯法又称为试探法,按选优条件向前搜索,当搜索到某一步发现原先选择并不优或达不到目标时,就退回一步重新选择。
- 动态规划 - 基本思想也是将待求解问题分解成若干个子问题,先求解并保存这些子问题的解,避免产生大量的重复运算。
排序算法(选择、冒泡和归并)和查找算法(顺序和折半)
def select_sort(items, comp=lambda x, y: x < y): """简单选择排序""" items = items[:] for i in range(len(items) - 1): min_index = i for j in range(i + 1, len(items)): if comp(items[j], items[min_index]): min_index = j items[i], items[min_index] = items[min_index], items[i] return items
def bubble_sort(items, comp=lambda x, y: x > y): """冒泡排序""" items = items[:] for i in range(len(items) - 1): swapped = False for j in range(i, len(items) - 1 - i): if comp(items[j], items[j + 1]): items[j], items[j + 1] = items[j + 1], items[j] swapped = True if not swapped: break return items
def bubble_sort(items, comp=lambda x, y: x > y): """搅拌排序(冒泡排序升级版)""" items = items[:] for i in range(len(items) - 1): swapped = False for j in range(i, len(items) - 1 - i): if comp(items[j], items[j + 1]): items[j], items[j + 1] = items[j + 1], items[j] swapped = True if swapped: swapped = False for j in range(len(items) - 2 - i, i, -1): if comp(items[j - 1], items[j]): items[j], items[j - 1] = items[j - 1], items[j] swapped = True if not swapped: break return items
def merge(items1, items2, comp=lambda x, y: x < y): """合并(将两个有序的列表合并成一个有序的列表)""" items = [] index1, index2 = 0, 0 while index1 < len(items1) and index2 < len(items2): if comp(items1[index1], items2[index2]): items.append(items1[index1]) index1 += 1 else: items.append(items2[index2]) index2 += 1 items += items1[index1:] items += items2[index2:] return items def merge_sort(items, comp=lambda x, y: x < y): return _merge_sort(list(items), comp) def _merge_sort(items, comp): """归并排序""" if len(items) < 2: return items mid = len(items) // 2 left = _merge_sort(items[:mid], comp) right = _merge_sort(items[mid:], comp) return merge(left, right, comp)
def seq_search(items, key): """顺序查找""" for index, item in enumerate(items): if item == key: return index return -1
def bin_search(items, key): """折半查找""" start, end = 0, len(items) - 1 while start <= end: mid = (start + end) // 2 if key > items[mid]: start = mid + 1 elif key < items[mid]: end = mid - 1 else: return mid return -1
贪婪
回溯法例子:骑士巡逻。
动态规划例子:子列表元素之和的最大值。
def main(): items = list(map(int, input().split())) overall = partial = items[0] for i in range(1, len(items)): partial = max(items[i], partial + items[i]) overall = max(partial, overall) print(overall)
分治法:快速排序
"""快速排序 - 选择枢轴对元素进行划分,左边都比枢轴小右边都比枢轴大""" def quick_sort(items, comp=lambda x, y: x <= y): items = list(items)[:] _quick_sort(items, 0, len(items) - 1, comp) return items def _quick_sort(items, start, end, comp): if start < end: pos = _partition(items, start, end, comp) _quick_sort(items, start, pos - 1, comp) _quick_sort(items, pos + 1, end, comp) def _partition(items, start, end, comp): pivot = items[end] i = start - 1 for j in range(start, end): if comp(items[j], pivot): i += 1 items[i], items[j] = items[j], items[i] items[i + 1], items[end] = items[end], items[i + 1] return i + 1