Python - l00jj/algorithm GitHub Wiki
Python
技巧
换行
如果当前代码太长需要换行,不能直接换行,可以在截断位置加入\后再换行即可,一下两段代码等效
while a and \
b:
# 等价于
while a and b:
继续解包
items = [1,2],[2,4](/l00jj/algorithm/wiki/1,2],[2,4)
for idx,(profit,categorie) in enumerate(items):
print(idx,profit,categorie)
or 排空返回
a, b = None, 1
return a or b # 1
字母顺序类
log = {ch: w for ch, w in zip(chars, vals)}
for i, ch in enumerate(ascii_lowercase, 1): log.setdefault(ch, i)
统计
数组内特定统计某个数出现次数
[0,0,0,1].count(1)
与Java的Integer.bit_count功能一致的函数
(5).bit_count() # 3
倒序对比
a == a[::-1],字符串头部与结尾双指针对比,常用于回文判断
使用defaultdict修改默认行为
dic = defaultdict(int)
dic[0] += 1
dic[-1] = 1
二分查找bisect
bisect_left 是有相同值出现,优先插左边
bisect_right 是有相同值出现,优先插右边,等于高效版bisect_left(nums, target, key = lambda v: v - 1)
python 采用相似对比的原则,如果target是一个int,那么nums中对比的也是int,如果nums是一个二维或多维数组,可以用自定义key进行精确获取,也可以直接改变target,例如当前是一组二维数组,需要对比的是子数组中第一个数值,可以bisect_left(nums, [target]),把target转成数组。
二分查找某一区域长度
arr = [int...], 在arr内找出数值最小为left,最大为right,对应的最大区域长度或区域下标
bisect_right(arr, right) - bisect_left(arr, left)
排序指南
https://docs.python.org/zh-cn/3/howto/sorting.html#sortinghowto 通常情况下,如果不显式加入指示,默认是对比成员本身或成员的第一个成员,指南内有对应的说明如何更改这个情况。
Zip
在多个迭代器上并行迭代,从每个迭代器返回一个数据项组成元组。
print(list(zip(range(4),range(5),range(6),range(7))))
# [(0, 0, 0, 0), (1, 1, 1, 1), (2, 2, 2, 2), (3, 3, 3, 3)]
pairwise 重叠输出
pairwise('ABCDEFG')
# --> AB BC CD DE EF FG
print(dict(pairwise('croakc'[::-1])))
# --> {'c': 'k', 'k': 'a', 'a': 'o', 'o': 'r', 'r': 'c'}
permutations 全部排列组合枚举器
combinations = itertools.permutations([a, b, c])
for combination in combinations:
print(combination)
# (a,b,c) ... (c,b,a)
平衡树
from sortedcontainers import SortedList
class Solution:
def minAbsoluteDifference(self, nums: List[int], x: int) -> int:
ans = inf
sl = SortedList((-inf, inf)) # 哨兵
for v, y in zip(nums, nums[x:]):
sl.add(v)
j = sl.bisect_left(y)
ans = min(ans, sl[j] - y, y - sl[j - 1])
return ans
函数如何引入比较器
import operator
operator.add
operator.xor
叠加器/累加器
# http://study.yali.edu.cn/pythonhelp/library/itertools.html#itertools.accumulate
itertools.accumulate(iterable[, func, *, initial=None])
[v for v in enumerate(accumulate(list, operator.mul))]
# http://study.yali.edu.cn/pythonhelp/library/functools.html?highlight=reduce#functools.reduce
functools.reduce(function, iterable[, initializer])
横表转竖表
# 横表转竖表
t = []
t.append(list(accumulate((i[0] for i in col), initial = 0)))
如何定义参数和使用
(num=123,val) 报错,带默认值的参数必须放在最后 (val,*,num=123)这个*用于隔断之前的值,如果要修改最后num的值,需要在使用的时候fun(1,num=7)这样修改
https://www.cnblogs.com/happyyangyanghappy/p/17085375.html
优先堆的使用
它主要的特点是需要一个额外的数列,并且原地修改这个数列,如果是pop这种弹出操作,数列会真实减少长度 http://study.yali.edu.cn/pythonhelp/library/heapq.html
巧用优先堆API获取最小n个值
nsmallest
nsmallest([],3)可以获取最小 3 个值
List的下标取值范围
可以看到,-5%3本应是-2越界查询,但是python会识别出需要尽量在数列内找到一个下标所以自动+3找到下标1返回,但直接-2是表示倒数第二个的意思
counter = [0] * 10
counter[-5 % 3] = 1
counter[-2] = 2
print(counter)
获取参数
141. 环形链表 题目设有隐藏参数,而这个参数直接可以解题,所以只要能获取这个参数就能 O(1) 解。
f = open("user.out", "w")
while True:
try:
param_1 = input()
param_2 = int(input())
f.write('true\n' if param_2 > -1 else 'false\n')
except:
break
exit()
numpy
argpartition
numpy.argpartition
找到数组中第 a 个最小值的并返回下标列表
import numpy as np
a = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
indices = np.argpartition(a, 3)
print(indices) # [0 1 2]
partition
numpy.partition
找到数组中第 a 个最小值的并返回数值列表
import numpy as np
a = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
smallest_three = np.partition(a, 3)[:3]
print(smallest_three) # [1 2 3]
count_nonzero
numpy.count_nonzero
统计非0非None的数量
import numpy as np
class Solution:
def maxDivScore(self, nums: List[int], divisors: List[int]) -> int:
nums = np.array(nums, dtype=np.int32)
score = [np.count_nonzero(nums % i) for i in divisors]
i = min(range(len(divisors)), key=lambda x: (score[x], divisors[x]))
return divisors[i]