此篇文章总结的数据类型/数据结构包括list, set, dict, collections.deque, heap
1. List
| Operation | Example | Complexity Class | Notes |
|---|
| Index | l[i] | O(1) | |
| Store | l[i] = 0 | O(1) | |
| Length | len(l) | O(1) | |
| Append | l.append(5) | O(1) | |
| Pop | l.pop() | O(1) | 等同于l.pop(-1) |
| Pop | l.pop(i) | O(N) | O(N-i): l.pop(0):O(N) (see above) |
| Containment | x in/not in s | O(N) | linearly searches list |
| Clear | l.clear() | O(1) | 类似于 l = [] |
| Slice | l[a:b] | O(b-a) | l[1:5]:O(l); l[:]:O(len(l)-0)=O(N) |
| Extend | l.extend(...) | O(len(...)) | depends only on len of extension |
| check ==, != | l1 == l2 | O(N) | |
| Insert | l[a:b] = ... | O(N) | |
| Delete | del l[i] | O(N) | depends on i; O(N) in worst case |
| Copy | l.copy() | O(N) | 等同于slice全部 |
| Remove | l.remove(a) | O(N) | 移除list中第一个a |
| Extreme value | min(l)/max(l) | O(N) | 线性搜索list |
| Reverse | l.reverse() | O(N) | |
| Iteration | for v in l: | O(N) | Worst: no return/break in loop |
| Sort | l.sort() | O(N Log N) | key/reverse mostly doesn't change |
| Multiply | k*l | O(k N) | 5*l is O(N); len(l)*l is O(N**2) |
| Construction | list(...) | O(len(...)) | depends on length of ... iterable |
Tuples支持所有不改变数据结构的操作(它们具有相同的复杂度)。
2. Set
| Operation | Example | Complexity | Notes |
|---|
| Length | len(s) | O(1) | |
| Add | s.add(5) | O(1) | |
| Containment | x in/not in s | O(1) | compare to list/tuple - O(N) |
| Remove | s.remove(..) | O(1) | compare to list/tuple - O(N) |
| Discard | s.discard(..) | O(1) | 如果元素不存在,discard不会报错,remove会报错 |
| Pop | s.pop() | O(1) | 随机pop一个元素 |
| Clear | s.clear() | O(1) | similar to s = set() |
| check ==, != | s != t | O(len(s)) | same as len(t); False in O(1) if the lengths are different |
| <=/< | s <= t | O(len(s)) | issubset |
| >=/> | s >= t | O(len(t)) | issuperset;s <= t == t >= s |
| Union | s | t | O(len(s)+len(t)) |
| Intersection | s & t | O(min(len(s), len(t))) | t不一定需要是set,当t不是set时,复杂度计算要把min换成max |
| Difference | s - t | O(len(s) | 求差集是把在s中不在t中的元素加到新的集合里 |
| 更新为差集 | s.difference_update(t) | O(len(t)) | 更新为差集是把t中元素从s中移除 |
| Symmetric Diff | s ^ t | O(len(s)+len(t)) | 删除两个集合中都存在的元素 |
| Iteration | for v in s: | O(N) | Worst: no return/break in loop |
| Copy | s.copy() | O(N) | |
| Construction | set(...) | O(len(...)) | depends on length of ... iterable |
相比于list和tuple,set多了很多O(1)的操作
3. dict and defaultdict
| Operation | Example | Complexity | Notes |
|---|
| Index | d[k] | O(1) | |
| Store | d[k] = v | O(1) | |
| Length | len(d) | O(1) | |
| Delete | del d[k] | O(1) | |
| get/setdefault | d.get(k) | O(1) | |
| Pop | d.pop(k) | O(1) | |
| Pop item | d.popitem() | O(1) | popped item "randomly" selected |
| Clear | d.clear() | O(1) | similar to s = {} or = dict() |
| View | d.keys() | O(1) | same for d.values() |
| Construction | dict(...) | O(len(...)) | depends # (key,value) 2-tuples |
| Iteration | for k in d: | O(N) | all forms: keys, values, items; Worst: no return/break in loop |
4. Collections.deque
deque (double-ended queue,双向队列)是以双向链表的形式实现的 (Well, a list of arrays rather than objects, for greater efficiency)。双向队列的两端都是可达的,但从查找队列中间的元素较为缓慢,增删元素就更慢了。
| Operation | Example | Complexity | Notes |
|---|
| Append | d.append() | O(1) | |
| Appendleft | d.appendleft() | O(1) | |
| Pop | d.pop() | O(1) | |
| Popleft | d.popleft() | O(1) | |
| Extend | d.extend() | O(k) | |
| Extendleft | d.extendleft() | O(k) | |
| Rotate | d.rotate() | O(k) | |
| Remove | d.remove(..) | O(n) | |
deque是线程安全的,可以同时从deque的左边和右边进行操作。
可以用deque(maxlen=n)设置deque长度,超过长度时会从另一边自动删除。
5. Heapq
| Operation | Example | Complexity | Notes |
|---|
| Push | heapq.heappush(heap, item) | O(logN) | |
| Pop | heapq.heappop(heap) | O(logN) | 弹出并返回堆中的最小项,保持堆不变。如果堆是空的,则引发IndexError。 |
| Push+Pop | heapq.heappushpop(heap, item) | O(logN) | 比组合调用push+pop更有效率 |
| Heapify | heapq.heapify(x) | O(logN) | |
| Replace | heapq.heapreplace(n) | O(logN) | pop smallest item and push new item, 比pop+push更有效率 |