数学与计算
math
模块
math
模块提供了一系列常用的数学函数和常量,适用于需要高效计算的场景。以下是一些重要的函数:
-
math.gcd(a, b)
计算两个整数的最大公约数 (GCD)。print(math.gcd(48, 18)) # 输出: 6
-
math.lcm(a, b)
(Python 3.9+)
计算两个整数的最小公倍数 (LCM)。print(math.lcm(48, 18)) # 输出: 144
-
math.sqrt(x)
返回非负数x
的平方根。print(math.sqrt(16)) # 输出: 4.0
-
math.factorial(x)
返回整数x
的阶乘。print(math.factorial(5)) # 输出: 120
-
math.log(x, base)
计算以base
为底的x
的对数,若未指定base
,则默认为自然对数。print(math.log(8, 2)) # 输出: 3.0
-
math.comb(n, k)
(Python 3.8+)
返回从n
个元素中选取k
个元素的组合数。print(math.comb(5, 2)) # 输出: 10
-
math.perm(n, k)
(Python 3.8+)
返回从n
个元素中选取k
个元素的排列数。print(math.perm(5, 2)) # 输出: 20
数据结构与算法
queue
模块
queue
模块提供了多种线程安全的队列数据结构,适用于多线程编程和任务调度等场景。常用的队列包括 Queue
(先进先出)、LifoQueue
(后进先出)和 PriorityQueue
(优先级队列)。下面介绍它们的主要功能及使用方法:
queue.Queue
:这是一个先进先出(FIFO)队列,按插入顺序处理元素。
-
Queue.put(item)
将元素添加到队列末尾。q = queue.Queue() q.put(1) q.put(2) q.put(3)
-
Queue.get()
从队列中获取并移除最先插入的元素。item = q.get() print(item) # 输出: 1
-
Queue.qsize()
返回队列中当前的元素数量。print(q.qsize()) # 输出: 2
-
Queue.empty()
判断队列是否为空。print(q.empty()) # 输出: False (队列非空)
-
Queue.full()
判断队列是否已满(适用于有限大小的队列)。q = queue.Queue(maxsize=2) q.put(1) q.put(2) print(q.full()) # 输出: True
queue.LifoQueue
:这是一个后进先出(LIFO)队列,类似于栈结构。
-
LifoQueue.put(item)
将元素添加到队列顶端。stack = queue.LifoQueue() stack.put(1) stack.put(2) stack.put(3)
-
LifoQueue.get()
从队列顶端获取并移除元素。item = stack.get() print(item) # 输出: 3 (后进先出)
queue.PriorityQueue
:优先级队列,元素按优先级顺序处理,优先级值越小,优先级越高。
-
PriorityQueue.put((priority, item))
将(优先级, 元素)
作为元组插入队列。pq = queue.PriorityQueue() pq.put((1, '任务1')) pq.put((2, '任务2'))
-
PriorityQueue.get()
获取优先级最高的元素。task = pq.get() print(task) # 输出: (1, '任务1')
collections
模块
collections
提供额外的数据结构,常见如下:
-
namedtuple
: 创建具有命名字段的元组。Point = namedtuple('Point', ['x', 'y']) p = Point(10, 20) print(p.x, p.y) # 例: 10 20
-
deque
: 双端队列,支持高效的两端操作。d = deque([1, 2, 3]) d.append(4) d.appendleft(0) print(d) # 例: deque([0, 1, 2, 3, 4])
-
Counter
: 统计可哈希对象的出现次数。counts = Counter(['a', 'b', 'a', 'c', 'b', 'a']) print(counts) # 例: Counter({'a': 3, 'b': 2, 'c': 1})
-
defaultdict
: 提供默认值避免KeyError
。dd = defaultdict(int) dd['a'] += 1 print(dd['a'], dd['b']) # 例: 1 0
heapq
模块
heapq
模块实现了堆队列算法,也称为优先队列。它提供了一系列函数来维护一个最小堆,使得每次获取的元素都是当前堆中最小的。以下是常用的 heapq
操作:
-
heapq.heappush(heap, item)
将元素item
添加到堆中,保持堆的性质。heap = [] heapq.heappush(heap, 3) heapq.heappush(heap, 1) heapq.heappush(heap, 5) print(heap) # 输出: [1, 3, 5]
-
heapq.heappop(heap)
移除并返回堆中的最小元素。smallest = heapq.heappop(heap) print(smallest) # 输出: 1
-
heapq.heapify(x)
将列表x
原地转换为堆,调整其内部结构,使其满足最小堆的性质。nums = [5, 2, 3, 1] heapq.heapify(nums) print(nums) # 输出: [1, 2, 3, 5]
-
heapq.nlargest(n, iterable, key=None)
返回可迭代对象中最大的n
个元素,按照指定的排序键(可选)。largest = heapq.nlargest(2, [1, 3, 5, 2, 4]) print(largest) # 输出: [5, 4]
-
heapq.nsmallest(n, iterable, key=None)
返回可迭代对象中最小的n
个元素。smallest = heapq.nsmallest(2, [1, 3, 5, 2, 4]) print(smallest) # 输出: [1, 2]
bisect
模块
bisect
模块用于在已排序的列表中高效地查找和插入元素,适用于二分查找的场景。在算法竞赛中,这个模块常用于需要快速定位插入点或保持有序列表的场景。
-
bisect.bisect_left(a, x)
查找元素x
在列表a
中的插入位置,使得插入后的列表仍然有序(偏左侧插入)。如果x
已存在,则插入到现有元素的左边。a = [1, 3, 4, 4, 5] position = bisect.bisect_left(a, 4) print(position) # 输出: 2
-
bisect.bisect_right(a, x)
查找元素x
在列表a
中的插入位置,使得插入后的列表保持有序(偏右侧插入)。如果x
已存在,则插入到现有元素的右边。position = bisect.bisect_right(a, 4) print(position) # 输出: 4
-
bisect.insort_left(a, x)
在列表a
中左侧插入元素x
,保持列表有序。如果x
已存在,插入到现有元素的左边。bisect.insort_left(a, 4) print(a) # 输出: [1, 3, 4, 4, 4, 5]
-
bisect.insort_right(a, x)
在列表a
中右侧插入元素x
,保持列表有序。如果x
已存在,插入到现有元素的右边。bisect.insort_right(a, 4) print(a) # 输出: [1, 3, 4, 4, 4, 5]
输入输出与系统管理
sys
模块
sys
模块提供与 Python 解释器及其环境相关的功能,在算法竞赛中常用于优化输入输出、管理递归深度等,有助于提升程序效率。
-
sys.stdin.readline()
从标准输入中读取一行数据,通常用于处理大规模输入时,可以比input()
更高效,因为它不会去除行末的换行符。line = sys.stdin.readline() # 读取一行输入 print(line.strip()) # 输出并去除行末的换行符
-
sys.stdin
和sys.stdout
当需要处理大规模的输入输出时,使用sys.stdin
和sys.stdout
会比input()
和print()
更高效。input = sys.stdin.read # 一次性读取所有输入 data = input().splitlines() # 按行分割输入 sys.stdout.write("输出结果\n") # 输出字符串,手动控制换行
-
sys.setrecursionlimit(limit)
设置递归调用的最大深度。Python 默认的递归深度为 1000,但在处理深度递归时可能不够,需要手动增加限制,避免RecursionError
。sys.setrecursionlimit(10**6) # 将递归深度设置为 10^6
-
sys.exit(status)
立即终止程序执行,并返回状态码。通常,status
为 0 表示正常退出,非 0 表示异常退出。sys.exit(0) # 正常退出程序
-
sys.argv
用于获取命令行参数。它以列表形式存储所有传递给脚本的参数,其中第一个元素是脚本名称,后续元素为传递的参数。print(sys.argv) # 输出: ['script_name.py', 'arg1', 'arg2']
datetime
模块
datetime
模块提供了处理日期和时间的类与方法,适合涉及时间计算、日期比较等场景。
-
datetime.datetime.now()
获取当前的日期和时间。import datetime now = datetime.datetime.now() print(now) # 输出: 2024-09-07 14:05:45.123456
-
datetime.timedelta
用于表示两个时间之间的差值,可以进行加减运算。from datetime import datetime, timedelta now = datetime.now() delta = timedelta(days=5) future = now + delta print(future) # 输出: 当前时间 + 5 天后的日期
-
datetime.datetime.strptime(date_string, format)
将字符串按照指定格式解析为datetime
对象。date_str = "2024-09-07" date = datetime.strptime(date_str, "%Y-%m-%d") print(date) # 输出: 2024-09-07 00:00:00
-
datetime.datetime.strftime(format)
将datetime
对象格式化为字符串,便于输出特定的日期格式。now = datetime.now() date_str = now.strftime("%Y-%m-%d %H:%M:%S") print(date_str) # 输出: 2024-09-07 14:05:45
-
datetime.datetime.timestamp()
获取datetime
对象对应的 Unix 时间戳。timestamp = now.timestamp() print(timestamp) # 输出: 时间戳,例如 1694107545.123456
calendar
模块
calendar
模块提供了一些操作日历相关数据的实用函数,适合需要处理日期、月份等场景。
-
calendar.monthrange(year, month)
返回指定年份和月份的第一个星期几和该月的天数。import calendar first_weekday, num_days = calendar.monthrange(2024, 9) print(first_weekday, num_days) # 输出: (6, 30) 表示 9 月的第一个是星期天,有 30 天
-
calendar.isleap(year)
判断指定年份是否为闰年。print(calendar.isleap(2024)) # 输出: True
-
calendar.weekday(year, month, day)
返回指定日期是星期几,0 表示星期一,6 表示星期日。weekday = calendar.weekday(2024, 9, 7) print(weekday) # 输出: 5 (表示星期六)
-
calendar.calendar(year)
打印指定年份的日历。print(calendar.calendar(2024))
迭代器与生成器
itertools
模块
itertools
提供高效的迭代工具,常见函数如下:
-
itertools.count(start=0, step=1)
: 创建一个从start
开始,每次增加step
的无限迭代器。counter = itertools.count(start=5, step=2) print([next(counter) for _ in range(5)]) # 例: [5, 7, 9, 11, 13]
-
itertools.cycle(iterable)
: 无限循环遍历可迭代对象。cyclic = itertools.cycle(['A', 'B', 'C']) print([next(cyclic) for _ in range(6)]) # 例: ['A', 'B', 'C', 'A', 'B', 'C']
-
itertools.permutations(iterable, r=None)
: 返回元素的所有排列。perms = itertools.permutations('ABCD', 2) print(list(perms)) # 例: [('A', 'B'), ('A', 'C'), ...]
-
itertools.combinations(iterable, r)
: 返回元素的所有组合。combs = itertools.combinations('ABCD', 2) print(list(combs)) # 例: [('A', 'B'), ('A', 'C'), ...]
-
itertools.product(*iterables, repeat=1)
: 生成笛卡尔积。prod = itertools.product('AB', repeat=2) print(list(prod)) # 例: [('A', 'A'), ('A', 'B'), ...]
functools
模块
functools
提供了函数工具,主要用于函数的缓存和高阶函数的操作。以下是一些有用的函数:
-
functools.lru_cache(maxsize=None)
使用最近最少使用 (LRU) 策略缓存函数的返回结果,提升带有重复计算的递归算法的性能。import functools @functools.lru_cache(maxsize=None) def fib(n): if n < 2: return n return fib(n-1) + fib(n-2) print(fib(50)) # 输出: 12586269025
-
functools.reduce(function, iterable)
累积地应用function
到iterable
的元素,从而将其减少为单个值。from functools import reduce numbers = [1, 2, 3, 4, 5] result = reduce(lambda x, y: x * y, numbers) print(result) # 输出: 120
-
functools.cmp_to_key(func)
将旧式的比较函数func
转换为一个可以用于排序的键函数。这个函数在 Python 3 中尤其有用,因为排序函数不再直接支持比较函数。from functools import cmp_to_key # 比较函数 def compare(x, y): return x - y # 从小到大排序 # 转换为键函数 key_func = cmp_to_key(compare) # 使用转换后的键函数进行排序 data = [5, 2, 9, 1, 5, 6] data.sort(key=key_func) print(data) # 输出: [1, 2, 5, 5, 6, 9]
-
functools.partial(func, \*args, \**keywords)
创建一个新的函数,固定某些参数的值,并返回该函数。from functools import partial def power(base, exponent): return base ** exponent square = partial(power, exponent=2) # 固定 exponent 为 2 print(square(5)) # 输出: 25
随机数生成
random
模块
random
模块用于生成伪随机数,支持生成整数、浮点数、随机选择等。常用功能如下:
-
random.random()
: 生成[0.0, 1.0)
的随机浮点数。print(random.random()) # 例: 0.3744
-
random.randint(a, b)
: 生成[a, b]
的随机整数。print(random.randint(1, 10)) # 例: 7
-
random.uniform(a, b)
: 生成[a, b]
的随机浮点数。print(random.uniform(1.5, 10.5)) # 例: 7.12
-
random.choice(seq)
: 从序列中随机选择一个元素。print(random.choice([1, 2, 3, 4, 5])) # 例: 3
-
random.choices(population, weights=None, k=1)
: 随机选择k
个元素。print(random.choices([1, 2, 3, 4, 5], k=3)) # 例: [4, 1, 5]
-
random.sample(population, k)
: 随机选择k
个不重复元素。print(random.sample([1, 2, 3, 4, 5], k=3)) # 例: [2, 5, 3]
-
random.shuffle(seq)
: 原地打乱序列顺序。lst = [1, 2, 3, 4, 5] random.shuffle(lst) print(lst) # 例: [3, 1, 5, 2, 4]
-
random.gauss(mu, sigma)
: 生成正态分布随机数。print(random.gauss(0, 1)) # 例: -0.49
-
random.seed(a=None)
: 初始化随机数生成器。random.seed(42) print(random.random()) # 例: 0.6394
-
random.getrandbits(k)
: 生成k
位的随机整数。print(random.getrandbits(16)) # 例: 57856