【算竞模板】Python:常用模块

数学与计算

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.stdinsys.stdout
    当需要处理大规模的输入输出时,使用 sys.stdinsys.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)
    累积地应用 functioniterable 的元素,从而将其减少为单个值。

    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
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值