[关闭]
@thousfeet 2022-03-25T15:35:50.000000Z 字数 10404 阅读 407

python模板整理

LeetCode


读写文件

  1. # 读
  2. with open("xx.txt","r") as f:
  3. article = f.read() # 返回字符串
  4. line = f.readline()
  5. lines = f.readlines() # 返回字符串列表
  6. # 写
  7. f = open('xx.txt','w')
  8. f.write('...') # 直接覆盖
  9. f = open('xx.txt','a')
  10. f.write('...') # 追加写入

控制台读入

  1. a = input()

格式化输出 format

  1. >>> print('{} {}'.format('hello','world')) # 不带字段
  2. hello world
  3. >>> print('{0} {1} {0}'.format('hello','world')) # 带数字编号
  4. hello world hello
  5. >>> print('{a} {tom} {a}'.format(tom='hello',a='world')) # 带关键字
  6. world hello world
  7. >>> print('{:f}'.format(20)) # 浮点
  8. 16 20.000000

main 函数

  1. def main(argv=None):
  2. if argv is None:
  3. argv = sys.argv
  4. pass
  5. if __name__ == "__main__":
  6. sys.exit(main())

类继承

  1. class A:
  2. def __init__(self):
  3. self.x = 0
  4. class B(A):
  5. def __init__(self):
  6. super().__init__()
  7. self.y = 1

字符串操作

join()

  1. s = "-"
  2. seq = ("a", "b", "c") # This is sequence of strings.
  3. print(s.join(seq))

split()

对字符串进行切片,默认为所有的空字符,包括空格、换行(\n)、制表符(\t)等,如果第二个参数 num 有指定值,则分割为 num+1 个子字符串(切num次)。

str.split(str, num)

  1. print (str.split( )) # 以空格为分隔符
  2. print (str.split('i',1)) # 以 i 为分隔符

多个分隔符

  1. re.split(r"[;,?]", line)

strip()

移除字符串头尾指定的字符(默认为空格或换行符)或字符序列。

str.strip([chars])

  1. s = s.strip() #去除首尾空格
  2. s = s.strip('01') #去除首尾字符0或1

replace()

把字符串中的旧字符串替换成新字符串,如果指定第三个参数max,则替换不超过 max 次。

str.replace(old, new[, max])

  1. s = s.replace("is", "was")

count()

统计字符串里某个字符或子字符串出现的次数

str.count(sub, start= 0,end=len(string))

  1. str.count("i")

ord()

以一个字符(长度为1的字符串) 作为参数,返回对应的 ASCII 或者 Unicode 数值。配对函数是chr()。

  1. ord(c)

isdigit()

判断字符串是否全为数字组成

  1. str.isdigit()

string转int

  1. int(str)

string数组转为int数组

  1. results = list(map(int, results))

list 数组

初始化

  1. b = [0 for _ in range(10)] #也可以b = [0]*10
  2. //二维
  3. a = [[0 for i in range(m)] for j in range(n)]

末尾元素

  1. a[-1]

判断存在

  1. if x in List

逆序遍历

  1. a = [1,3,6,8,9]
  2. for i in a[::-1]:
  3. print(i)
  4. for i in range(len(a)-1,-1,-1):
  5. print(a[i])

查找列表中某个值value的位置

  1. p=list.index(value)

逆着反向找

  1. p=list.rindex(value)

去除list中的空字符串

  1. arr = list(filter(None, arr))

插入 insert()

在index位置插入obj

  1. list.insert(index, obj)

得到所有元素平方的list

  1. x = [1,2,3,4,5]
  2. # map
  3. def square(num):
  4. return num*num
  5. list(map(square,x))
  6. #lambda
  7. list(map(lambda num:num*num, x))
  8. # list comprehensions
  9. [num*num for num in x]

排序sort()/sorted()

list.sort() 方法只可用于list,而 sorted() 函数可以接受任何可迭代对象

  1. list.sort() #直接修改原list
  2. list.sort(cmp=None, key=None, reverse=False)
  3. lis = sorted(dic, key=abs) #将dic的key按照abs排序的key list

key的使用

使用对象的索引作为key:

  1. student_tuples = [
  2. ('john', 'A', 15),
  3. ('jane', 'B', 12),
  4. ('dave', 'B', 10),
  5. ]
  6. student_tuples = sorted(student_tuples, key=lambda student: student[2]) # sort by age

对具有命名属性的对象:

  1. class Student:
  2. def __init__(self, name, grade, age):
  3. self.name = name
  4. self.grade = grade
  5. self.age = age
  6. def __repr__(self):
  7. return repr((self.name, self.grade, self.age))
  8. student_objects = [
  9. Student('john', 'A', 15),
  10. Student('jane', 'B', 12),
  11. Student('dave', 'B', 10),
  12. ]
  13. sorted(student_objects, key=lambda student: student.age) # sort by age
  14. sorted(student_objects, key=lambda student: (student.grade, student.age))

使用 itemgetter() 、 attrgetter() 和 methodcaller() 函数:

  1. from operator import itemgetter, attrgetter
  2. sorted(student_tuples, key=itemgetter(2))
  3. sorted(student_objects, key=attrgetter('age'))

多级排序:

按 grade 降序然后 age 升序对学生数据进行排序:先 age 排序,然后再使用 grade 排序:

  1. s = sorted(student_objects, key=attrgetter('age')) # sort on secondary key
  2. sorted(s, key=attrgetter('grade'), reverse=True) # sort on primary key
  3. [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

对二维lists进行排序。对于每个list,其他位置降序排序,第num个位置升序排序:

  1. s = sorted(lists, key=lambda x: x[num])
  2. s = sorted(s, key=lambda x: x[:num], reverse=True)

zip()

参数为可迭代的对象。将对象中对应的元素打包成一个个元组,返回由这些元组组成的generator。

zip([iterable, ...])

  1. >>>a = [1,2,3]
  2. >>> b = [4,5,6]
  3. >>> list(zip(a,b))
  4. [(1, 4), (2, 5), (3, 6)]
  5. >>> a1, a2 = zip(*zip(a,b)) #zip(*...) 解压,返回二维矩阵式
  6. >>> list(a1)
  7. [1, 2, 3]

可以用于快速构造dict:

  1. keys, values = [1,2,3], [2,3,4]
  2. dict(zip(keys, values))

可以用于转置or旋转二维矩阵

  1. matrix = [[1,2,3],
  2. [4,5,6],
  3. [7,8,9]]
  4. list(zip(*matrix)) # [(1, 4, 7), (2, 5, 8), (3, 6, 9)] 相当于转置
  5. list(zip(*matrix))[::-1] # [(3, 6, 9), (2, 5, 8), (1, 4, 7)] 逆时针旋转

enumerate()

作用于一个可遍历的数据对象,返回下标和数据

enumerate(sequence, [start=0])

  1. >>>seasons = ['Spring', 'Summer', 'Fall', 'Winter']
  2. >>> list(enumerate(seasons))
  3. [(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]
  4. >>> list(enumerate(seasons, start=1)) # 下标从 1 开始
  5. [(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')]

dict 字典

类似map的使用

初始化一个空dict

  1. dic = {}

添加元素

  1. if x in dic: dic[x]+=1
  2. else: dic[x]=1

删除元素

  1. dic.pop(x) # x是key

遍历

  1. for x in dic: # x是key

get(key, default=None) 返回指定键的值,如果值不在字典中返回默认值

  1. dict = {'Name': 'Runoob', 'Age': 27}
  2. dict.get('Sex', "Never") #Never

将字典中的值转换成list

  1. list(dic.values())
  2. list(dic.keys())

按key排序 (直接sorted返回的是list)

  1. dic = dict(sorted(dic.items()) #默认就是按key排序
  2. dic = dict(sorted(dic.items(), key=lambda x: x[1])) #按value排序

queue 队列

  1. #向队列中添加元素
  2. Queue.put(item[, block[, timeout]])
  3. #从队列中获取元素并删除
  4. Queue.get([block[, timeout]])
  5. #队列判空
  6. Queue.empty()
  7. #队列大小
  8. Queue.qsize()

优先队列(默认从小到大排序)

  1. from queue import PriorityQueue
  2. pq = PriorityQueue()
  3. pq.put((-x,x)) #构造元组使其从大到小排序

插入格式:q.put((priority number, data))
特点:priority number 越小,优先级越高
其他的操作和队列相同

  1. q = PriorityQueue()
  2. q.put((2, "Lisa"))
  3. q.put((1, "Lucy"))
  4. q.put((0, "Tom"))
  5. i = 0
  6. while i < q.qsize():
  7. print(q.get())
  8. # (0,"Tom")
  9. # (1,"Lucy")
  10. # (2,"Lisa")

或者用堆(PriorityQueue也是基于qheap实现的)

  1. import heapq
  2. heapq.heappushpop (heap, item):将item 放入堆中,然后弹出并返回heap 的最小元素
  3. heapq.heappush(heap, item):将 item 的值加入 heap 中,保持堆的不变性
  4. heapq.heappop(heap):弹出并返回 heap 的最小的元素,保持堆的不变性

双端队列

  1. from collections import deque
  2. d = collections.deque()
  3. d += element
  4. while d:
  5. d.pop()
  6. d.popleft()

stack 栈

用list就能直接模拟栈

  1. stack = [3, 4, 5]
  2. stack.append(6)
  3. stack.pop() #从栈顶取出元素

找lower/upper index

python的lower_bound是 bisect.bisect_left(nums, target)(值为target的第一个位置),upper_bound是 bisect.bisect(nums, target)(值为target的末尾位置+1)

collections

collections.Counter

list 的 counter:

  1. from collections import Counter
  2. myList = [1,1,2,3,4,5,3,2,3,4,2,1,2,3]
  3. Counter(myList) #Counter({2: 4, 3: 4, 1: 3, 4: 2, 5: 1})
  4. Counter(myList).items() #[(1, 3), (2, 4), (3, 4), (4, 2), (5, 1)]
  5. Counter(myList).keys() #[1, 2, 3, 4, 5]
  6. Counter(myList).values() #[3, 4, 4, 2, 1]
  1. c = Counter() # 创建一个新的空counter
  2. c = Counter('abcasdf') # 一个迭代对象生成的counter
  3. # Counter({'a': 2, 'c': 1, 'b': 1, 's': 1, 'd': 1})
  4. c = Counter({'red': 4, 'yello': 2}) # 一个映射生成的counter
  5. c = Counter(cats=2, dogs=5) # 关键字参数生成的counter

因为 Counter 实现了字典的 missing 方法, 所以当访问不存在的key的时候,返回值为0:

  1. c = Counter(['apple', 'pear'])
  2. c['orange'] #0

counter 常用的方法:

  1. # elements() 按照counter的计数,重复返回元素
  2. c = Counter(a=4, b=2, c=0, d=-2)
  3. list(c.elements())
  4. ['a', 'a', 'a', 'a', 'b', 'b']
  5. # most_common(n) 按照counter的计数,按照降序,返回前n项组成的list; n忽略时返回全部
  6. Counter('abracadabra').most_common(3)
  7. [('a', 5), ('r', 2), ('b', 2)]
  8. # subtract([iterable-or-mapping]) counter按照相应的元素,计数相减
  9. c = Counter(a=4, b=2, c=0, d=-2)
  10. d = Counter(a=1, b=2, c=3, d=4)
  11. c.subtract(d) #Counter({'a': 3, 'b': 0, 'c': -3, 'd': -6})
  12. # Counter 间的数学集合操作
  13. c = Counter(a=3, b=1, c=5)
  14. d = Counter(a=1, b=2, d=4)
  15. c + d # 相加
  16. #Counter({'c': 5, 'a': 4, 'd': 4, 'b': 3})
  17. c - d # 相减, 只保留正值value
  18. #Counter({'c': 5, 'a': 2})
  19. c & d # 交集: 取两者都有的key,value取小的那一个
  20. #Counter({'a': 1, 'b': 1})
  21. c | d # 并集: 汇聚所有的key, key相同的情况下,取大的value
  22. #Counter({'c': 5, 'd': 4, 'a': 3, 'b': 2})
  23. #常见做法:
  24. sum(c.values()) # 继承自字典的.values()方法返回values的列表,再求和
  25. c.clear() # 继承自字典的.clear()方法,清空counter
  26. list(c) # 返回key组成的list
  27. set(c) # 返回key组成的set
  28. dict(c) # 转化成字典
  29. c.items() # 转化成(元素,计数值)组成的列表
  30. Counter(dict(list_of_pairs)) # 从(元素,计数值)组成的列表转化成Counter
  31. c.most_common()[:-n-1:-1] # 最小n个计数的(元素,计数值)组成的列表
  32. c += Counter() # 利用counter的相加来去除负值和0的值

collections.defaultdict

普通的dict需要手动判是否存在和初始化,用defaultdict会方便一些
key不存在的value默认为0,可以直接赋值 如dp[i,j]=xxx

value是int:

  1. s = 'mississippi'
  2. d = defaultdict(int)
  3. for k in s:
  4. d[k] += 1
  5. d.items()
  6. #[('i', 4), ('p', 2), ('s', 4), ('m', 1)]

value是list:

  1. s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
  2. d = defaultdict(list)
  3. for k, v in s:
  4. d[k].append(v) #可以直接拿任意key放心做list的操作(包括extend等)不用担心not in dic
  5. d.items()
  6. #[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]

itertools.groupby

itertools.groupby(iterable[, key])
返回一个产生按照key进行分组后的值集合的迭代器.

  1. people = [[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]]
  2. for k, g in itertools.groupby(people, key=lambda x: x[0]): #以x[0]为key建组
  3. print(k, g) #key, group
  4. for x in g:
  5. #group 中的每一项

collections.OrderedDict

一个 dict 子类的实例,能重新排列字典顺序。
这个dict中如果有key值被覆盖的时候会被挪到末尾,相当于调用了move_to_end

popitem(last=True)
移除并返回一个 (key, value) 键值对。 如果 last 值为真,则按 LIFO 后进先出的顺序返回键值对,否则就按 FIFO 先进先出的顺序返回键值对。

move_to_end(key, last=True)
将现有 key 移动到有序字典的任一端。 如果 last 为真值(默认)则将元素移至末尾;如果 last 为假值则将元素移至开头。如果 key 不存在则会触发 KeyError:

  1. d = OrderedDict.fromkeys('abcde')
  2. d.move_to_end('b')
  3. ''.join(d.keys()) #'acdeb'
  4. d.move_to_end('b', last=False)
  5. ''.join(d.keys()) #'bacde'

数据结构模板相关

实时更新元素后求某区间和(307. Range Sum Query - Mutable

  1. # Your NumArray object will be instantiated and called as such:
  2. obj = NumArray(nums) # Initializes the object with the integer array nums
  3. obj.update(index,val) # Updates the value of nums[index] to be val
  4. param_2 = obj.sumRange(left,right) # Returns the sum of the elements of nums between indices left and right

1. 线段树

每个节点存储一个区间的左右的端点以及该区间的总和。叶节点存数组的元素,每个内部节点存储其下的叶子之和。创建树需要O(n)时间,查询和更新都是O(log n)。

  1. #Segment tree node
  2. class Node(object):
  3. def __init__(self, start, end):
  4. self.start = start
  5. self.end = end
  6. self.total = 0
  7. self.left = None
  8. self.right = None
  9. class NumArray(object):
  10. def __init__(self, nums):
  11. def createTree(nums, l, r):
  12. if l > r: return None
  13. #leaf node
  14. if l == r:
  15. n = Node(l, r)
  16. n.total = nums[l]
  17. return n
  18. mid = (l + r) // 2
  19. root = Node(l, r)
  20. root.left = createTree(nums, l, mid)
  21. root.right = createTree(nums, mid+1, r)
  22. root.total = root.left.total + root.right.total
  23. return root
  24. self.root = createTree(nums, 0, len(nums)-1)
  25. def update(self, i, val):
  26. def updateVal(root, i, val):
  27. if root.start == root.end:
  28. root.total = val
  29. return val
  30. mid = (root.start + root.end) // 2
  31. if i <= mid:
  32. updateVal(root.left, i, val)
  33. else:
  34. updateVal(root.right, i, val)
  35. root.total = root.left.total + root.right.total
  36. return root.total
  37. return updateVal(self.root, i, val)
  38. def sumRange(self, i, j):
  39. def rangeSum(root, i, j):
  40. #If the range exactly matches the root, we already have the sum
  41. if root.start == i and root.end == j:
  42. return root.total
  43. mid = (root.start + root.end) // 2
  44. #If end of the range is less than the mid, the entire interval lies
  45. #in the left subtree
  46. if j <= mid:
  47. return rangeSum(root.left, i, j)
  48. #If start of the interval is greater than mid, the entire inteval lies
  49. #in the right subtree
  50. elif i >= mid + 1:
  51. return rangeSum(root.right, i, j)
  52. #Otherwise, the interval is split. So we calculate the sum recursively,
  53. #by splitting the interval
  54. else:
  55. return rangeSum(root.left, i, mid) + rangeSum(root.right, mid+1, j)
  56. return rangeSum(self.root, i, j)

2. 树状数组

  1. class NumArray:
  2. def __init__(self, nums):
  3. self.arr = [0] * len(nums)
  4. self.BIT = [0] * (len(nums) + 1)
  5. for i, n in enumerate(nums): self.update(i, n)
  6. self.sumRange = lambda i, j: self.Sum(j + 1) - self.Sum(i)
  7. def update(self, i, val):
  8. diff, self.arr[i] = val - self.arr[i], val
  9. i += 1
  10. while i < len(self.BIT):
  11. self.BIT[i] += diff
  12. i += (i & -i) # to next
  13. def Sum(self, k):
  14. res = 0
  15. while k:
  16. res += self.BIT[k]
  17. k -= (k & -k) # to parent
  18. return res

Trie 树

  1. class TrieNode():
  2. def __init__(self):
  3. self.children = {}
  4. self.isEnd=False
  5. class Trie():
  6. def __init__(self):
  7. self.root = TrieNode()
  8. def insert(self, word):
  9. node = self.root
  10. for x in word:
  11. if x not in node.children:
  12. node.children[x] = TrieNode()
  13. node = node.children[x]
  14. node.isEnd = True

数学相关

最小公倍数

  1. def lcm(a, b):
  2. return abs(a*b) // math.gcd(a, b)

快速幂

  1. def power(bas,exp):
  2. ans, sqr = 1, bas
  3. while exp>0:
  4. if exp&1:
  5. ans = ans*sqr
  6. sqr = sqr*sqr
  7. exp >>= 1
  8. return ans

素数筛

  1. sieve = [True]*(n+1)
  2. for i in range(2,n):
  3. if sieve[i]:
  4. print(i)
  5. for j in range(i*i, n, i):
  6. sieve[j] = False
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注