defnum_reader(max=10): cache = 0 flag = False neg = False while chunk := read.read(): for byte in chunk: if48 <= byte <= 57: cache = (cache << 3) + (cache << 1) + byte - 48 flag = True continue
if flag: yield -cache if neg else cache cache = 0 flag = False neg = False
if byte == 45: neg = True
inp = num_reader()
输出
输出一行列表
依靠手动解包, 我们可以很简洁的输出列表
1
print(*lst)
假如需要换行.
1
print(*lst, sep="\n")
变量
变量交换
1 2 3
a, b = b, a # 甚至 a, b, c, d = c, d, a, b
解包
在输入命令那节, 我们用解包实现了命令和参数的拆解, 而现在是完整的性质.
1 2 3 4 5
a, *lst = line # 取出第一个元素和后续元素 a, *lst, b = line # 取出首尾元素和中间元素 a, *_, b = line # 如果你想省略中间元素 a, b, *lst = line # 嗯, 还可以取俩 a, *lst, b, c = line # 当然了, 前面再加一个也可以
from itertools import accumulate from operator import mul
prefix = list(accumulate(lst, func=mul))
for循环小技巧
当想要同时获取索引和元素时, 直接低级循环再取元素吗? 那太麻烦了吧!
1 2 3 4 5 6
# 0-base for i, v inenumerate(lst): ... # 1-base for i, v inenumerate(lst, 1): ...
是不是方便多了?
当一个列表需要枚举所有 l 和 r 的时候.
1 2 3 4
from itertools import product
for l, r in product(a, repeat=2): ...
当遇到两层 for 的时候.
1 2 3 4
from itertools import product
for ai, bi in product(a, b): ...
又假如需要将两个长度相等的列表一起遍历呢?
1 2
for ai, bi inzip(a, b): ...
或者说, 同一个数组想枚举相邻元素. (Python 3.10+)
1 2 3 4
from itertools import pairwise
for i, j in pairwise(lst): ...
或者是, 需要分批处理. (Python 3.12+)
1 2 3 4
from itertools import batched
for lst_n in batched(lst, n): ...
布尔数组加速
这是oiwiki上的线性筛:
1 2 3 4 5 6 7 8 9 10 11 12 13
defeuler_sieve(n): pri = [] not_prime = [False] * (n + 1) for i inrange(2, n + 1): ifnot not_prime[i]: pri.append(i) for pri_j in pri: if i * pri_j > n: break not_prime[i * pri_j] = True if i % pri_j == 0: break return pri
而这是优化过的:
1 2 3 4 5 6 7 8 9 10 11 12 13
defeuler_sieve(n): pri = [] not_prime = bytearray(n + 1) for i inrange(2, n + 1): ifnot not_prime[i]: pri.append(i) for p in pri: if i * p > n: break not_prime[i * p] = 1 if i % p == 0: break return pri