1、求解列表最大值及其下标:
max(zip(nums, range(len(nums))))
2、反转列表:
reversed(range(n))
下面的写法与上面的写法等价
range(n, -1, -1)
下面的写法也能实现列表反转, 但是a[3:-1:-1]不能实现边截取边反转,只能通过list(reversed(a[0:4]))实现
a[::-1]
3、二维列表的截取:
[[a[i][j] for j in range(n // 2)] for i in range(n //2)]
跟matlab不同的是,下面写法无法对列进行截取,因为a[:n // 2]本身是一个二维列表
a[:n//2][:n//2]
4、堆的使用,如果使用大顶堆,需要对数值取反:
import queue
q = queue.PriorityQueue()
q.put(num) #放置元素
q.qsize() #获取队列长度
q.get() #取出堆顶元素
q.queue[0] #获取堆顶元素
该模块(queue.PriorityQueue)是从下面的模块(heap)总封装成的,具有线程安全的特点
import heapq
heapq.heapify(nums) #堆排序数组
heapq.heappush(heap, num) #放入元素
heapq.heappop(heap) #取出堆顶元素
nums[0] #获取堆顶元素
5、排序,自定义排序比较函数
from functools import cmp_to_key
def compare(x, y):
return int(y+x) - int(x+y)
nums = sorted(map(str, nums), key=cmp_to_key(compare))
6、 if a: 既会判断 a 是否非None, 是否列表非空,是否字符串不为空串,是否不为0,相当于if bool(a):
7、使用迭代器中序遍历二叉树:
def inOrder(p):
if not p: return
yield from inOrder(p.left)
yield p.val
yield from inOrder(p.right)
print(list(inOrder(root)))
但是效率不如直接添加到数组,见二叉搜索树最近节点查询
8、二分查找
import bisect
bisect.bisect([2,3,5,6,7],5) #3
bisect.bisect_left([2,3,5,6,7], 5) #3
bisect.bisect_right([2,3,5,6,7], 5) #2
返回的插入点 i 可以将数组 a 分成两部分。左侧是 all(val < x for val in a[lo:i])
,右侧是 all(val >= x for val in a[i:hi])
参考资料:8.6. bisect — 数组二分查找算法 — Python 3.6.15 文档
【Python】详解 bisect 模块_闻韶-CSDN博客_bisect.bisect_left
此外,该函数不仅可以对固定数组进行二分查找,还可以根据输入求出表达式的值,例如:有序数组中的缺失元素
class Solution:
def missingElement(self, nums: List[int], k: int) -> int:
self.__class__.__getitem__ = lambda self, mid: nums[mid] - (nums[0] + mid) >= k
l = bisect.bisect_left(self, True, 0, len(nums))
return nums[l - 1] + k - (nums[l - 1] - (nums[0] + (l - 1)))
Python 3.10 支持通过 key
自定义二分规则: 例如:最小化两个数组中的最大值
class Solution:
def minimizeSet(self, d1: int, d2: int, uniqueCnt1: int, uniqueCnt2: int) -> int:
lcm = math.lcm(d1, d2)
def check(x: int) -> bool:
left1 = max(uniqueCnt1 - x // d2 + x // lcm, 0)
left2 = max(uniqueCnt2 - x // d1 + x // lcm, 0)
common = x - x // d1 - x // d2 + x // lcm
return common >= left1 + left2
return bisect_left(range((uniqueCnt1 + uniqueCnt2) * 2 - 1), True, key=check)
9、有序字典
from sortedcontainers import SortedDict as SD
sd = SortedDict({1: 3, 3: 1, 2: 2}) #SortedDict({1: 3, 2: 2, 3: 1})
idx = sd.bisect_right(2) #2
idx = sd.bisect_left(2) #1
sd.values()[idx] #2
10、有序列表
from sortedcontainers import SortedList
s = SortedList([])
s.add(("ds", 2))
s.add(("ad", 3))
print(s) #SortedList([('ad', 3), ('ds', 2)])
11、默认词典:
from collections import defaultdict
m = defaultdict(int)
m[0] += 1 #defaultdict(<class 'int'>, {0: 1})
12、 计数:
import collections
a = [1,2,3,4,2,4,5,2,3]
m = collections.Counter(a) #Counter({2: 3, 3: 2, 4: 2, 1: 1, 5: 1})
m.count(4) #2
13、lru缓存
from functools import lru_cache
@lru_cache()
def f(n):
if n <= 1: return n
return f(n - 1) + f(n - 2)
f(100) #354224848179261915075
14、按照频率将数组升序排序
sorted(nums, key = lru_cache(None)( lambda n: (nums.count(n), -n) ))
sum(iter(v for _,_,v in sorted((v,-k,[k]*v) for k,v in Counter(nums).items())),[])
15、求取前缀和
list(itertools.accumulate([1,2,3,4,5], initial=0)) #[0, 1, 3, 6, 10, 15]
16、找到二进制1的个数以及二进制的长度
print((n:=2).bit_count())
print((n:=2).bit_length())
17、求排列组合及数目
print(list(itertools.combinations([1,2,3,4], 2)))
#[(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)]
print(math.comb(4, 2)) # 6
print(list(itertools.permutations([1,2,3], 2)))
#[(1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2)]
print(math.perm(3, 2)) #6
print(math.factorial(6)) #720
18、求最大公约数和最小公倍数
math.gcd(4,6) #2
math.lcm(4, 6, 8) #24
19、reduce函数
reduce(lambda x,y: x*y, [1,2,3,4]) #24
20、pairwise函数
pairwise([1,2,3,4]) #[(1,2),(2,3),(3,4)]
21、取余定律
- 加法:
- 减法:
- 乘法:
- 幂运算:
除法取余涉及到逆元,可直接使用python自带的库
pow(a, -1, mod)
排列组合逆元:
class Permutation:
"""排列组合计算器"""
def __init__(self, mod: int = 10 ** 9 + 7):
self._mod = mod
self._size = 0
self._cache_factorial = [1] # 缓存阶乘
self._cache_factorial_inv = [1] # 缓存阶乘的乘法逆元
def factorial(self, n: int) -> int:
"""计算阶乘:n!"""
while self._size <= n:
self._size += 1
self._cache_factorial.append((self._cache_factorial[-1] * self._size) % self._mod)
self._cache_factorial_inv.append(pow(self._cache_factorial[-1], self._mod - 2, self._mod))
return self._cache_factorial[n]
def arrange(self, n: int, m: int) -> int:
"""计算排列数:A(n,m) (n>=m)"""
return (self.factorial(n) * self._cache_factorial_inv[n - m]) % self._mod
def comb(self, n: int, m: int) -> int:
"""计算组合数:C(n,m) (n>=m)"""
return (self.arrange(n, m) * self._cache_factorial_inv[m]) % self._mod
参考资料:
Python SortedContainers Module 对字典排序_阿茂丶-CSDN博客_sortedcontainers
Python| itertools之pairwise:获取连续的重叠对_lovetaozibaby的博客-CSDN博客_pairwise python排列组合计算器(包含乘法逆元)