【python】(8)标准库

2 阅读15分钟

time

time 库是 Python 标准库中的一部分,提供了与时间相关的功能,包括获取当前时间、时间格式化、时间延迟等。使用 time 库可以方便地处理时间相关的任务。

基本功能

获取当前时间戳

使用 time() 函数可以获取当前系统时间,返回自 1970 年 1 月 1 日零时以来的秒数(Unix 时间戳)。

import time

current_time = time.time()
print("Current time:", current_time)

性能计时

time.perf_counter()time.process_time()time.process_time_ns() 是用于测量时间的函数,它们的作用和用法如下:

1. time.perf_counter()

time.perf_counter() 函数返回一个性能计数器的值,这个值以秒为单位,用于测量程序执行的时间,包括睡眠时间。它是一个递增的浮点数,不受系统时钟的影响。

import time

start = time.perf_counter()

# 执行一些操作
time.sleep(1)

end = time.perf_counter()

execution_time = end - start
print("Execution time:", execution_time, "seconds")

2. time.process_time()

time.process_time() 函数返回当前进程的 CPU 时间,以秒为单位。它仅包括该进程在 CPU 上执行代码的时间,不包括睡眠时间或其他进程的时间。

import time

start = time.process_time()

# 执行一些操作
time.sleep(1)

end = time.process_time()

execution_time = end - start
print("Execution time:", execution_time, "seconds")

3. time.process_time_ns()

time.process_time_ns() 函数类似于 time.process_time(),但它返回的是纳秒(nanoseconds)级别的 CPU 时间,而不是秒。

import time

start = time.process_time_ns()

# 执行一些操作
time.sleep(1)

end = time.process_time_ns()

execution_time = (end - start) / 1e9  # 将纳秒转换为秒
print("Execution time:", execution_time, "seconds")

时间格式化

使用 ctime() 函数可以将时间戳格式化为可读的字符串表示。

formatted_time = time.ctime(current_time)
print("Formatted time:", formatted_time)

时间延迟

使用 sleep() 函数可以让程序休眠指定的秒数。

print("Start sleeping...")
time.sleep(3)
print("Wake up!")

时间元组

time 库中还定义了时间元组(struct_time),它是一个包含了年、月、日等时间信息的元组。常用的函数如下:

  • gmtime():获取当前的 UTC 时间。北京时间比这个时间早八小时。
  • localtime():获取当前的本地时间。
  • mktime():将时间元组转换为时间戳。
  • strptime():将字符串转换为时间元组。
# 获取当前的 UTC 时间
utc_time_tuple = time.gmtime()
print("UTC time tuple:", utc_time_tuple)

# 获取当前的本地时间
local_time_tuple = time.localtime()
print("Local time tuple:", local_time_tuple)

# 将时间元组转换为时间戳
timestamp = time.mktime(local_time_tuple)
print("Timestamp:", timestamp)

时间格式化字符串

time 库中定义了一些常用的时间格式化字符串,用于将时间元组或时间戳格式化为指定的字符串。

  • %Y:年份(4 位数)
  • %m:月份(01-12)
  • %d:日期(01-31)
  • %H:小时(00-23)
  • %M:分钟(00-59)
  • %S:秒(00-59)
formatted_local_time = time.strftime("%Y-%m-%d %H:%M:%S", local_time_tuple)
print("Formatted local time:", formatted_local_time)

性能计时

time 库也可以用于性能计时,以评估程序的执行时间。

start_time = time.time()

# 执行一些耗时操作
time.sleep(2)

end_time = time.time()
execution_time = end_time - start_time
print("Execution time:", execution_time, "seconds")

random

Python的random模块提供了生成伪随机数的工具。这些工具包括生成各种分布(如均匀、正态等)的随机数、随机选择元素、打乱序列等功能。这个模块是基于Mersenne Twister算法实现的,它是一个非常快速的伪随机数生成器,其周期长度达到2的19937次方减1。

基本使用

导入模块

在使用random模块之前,需要先导入它:

import random

生成随机数

  • 生成0到1之间的随机浮点数
n = random.random()
print(n)
  • 生成指定范围的随机整数
n = random.randint(a, b)  # 包括两端的a和b
print(n)
  • 生成指定范围内的随机浮点数
n = random.uniform(a, b)  # 包括a,不一定包括b
print(n)

序列操作

  • 从序列中随机选择一个元素
element = random.choice(['apple', 'pear', 'banana'])
print(element)
  • 从序列中随机选择k个元素
elements = random.sample(['apple', 'pear', 'banana'], k=2)
print(elements)
  • 随机打乱序列的顺序
items = [1, 2, 3, 4, 5]
random.shuffle(items)
print(items)

随机数分布

random模块还提供了生成特定分布随机数的函数,例如:

  • 正态分布随机数
n = random.normalvariate(mu, sigma)  # mu是均值,sigma是标准差
print(n)
  • 指数分布随机数
n = random.expovariate(lambd)  # lambd是率参数(1/mean)
print(n)

随机数种子

为了实现可重复的随机数序列,可以设置随机数生成的种子。当使用相同的种子时,random模块将会产生相同的随机数序列。

random.seed(a)  # a可以是任意哈希able对象

collection

Python的collections模块提供了一组用于处理容器数据类型的扩展,如字典、列表、集合、和元组等。这个模块实现了特定的容器数据类型,提供了Python标准内置容器数据类型的替代选择,旨在提供更高效、便利或常用的数据结构。以下是collections模块中一些重要类的详细介绍:

1. Counter

Counter是一个字典的子类,用于计数可哈希对象。它是一个集合,其中元素存储为字典的键,它们的计数存储为字典的值。

from collections import Counter

# 创建一个Counter对象
c = Counter(['a', 'b', 'c', 'a', 'b', 'b'])

# 访问计数
print(c['a'])  # 输出: 2
print(c['b'])  # 输出: 3

# 更新计数
c.update(['a', 'b', 'c', 'a'])
print(c)

# 计数的加减操作
c.subtract(['a', 'b'])
print(c)

# 获取出现次数最多的元素
print(c.most_common(2))

2. defaultdict

defaultdict是另一个字典的子类,它提供了一个默认值,用于字典访问时键不存在的情况。这可以减少检查键存在与否的代码量。

from collections import defaultdict

# 创建一个defaultdict对象,指定默认值类型为list
d = defaultdict(list)

# 添加元素
d['python'].append("awesome")
d['something'].append("not relevant")

# 访问不存在的键将返回一个空列表而不是引发KeyError
print(d['nokey'])

3. OrderedDict

在Python 3.7之前,字典类型不保证元素的顺序。OrderedDict是一个字典的子类,它保持了元素被添加的顺序。从Python 3.7开始,内置的dict类型已经保证了顺序,但OrderedDict依然有它的用途,比如提供了reversed()方法。

from collections import OrderedDict

# 创建一个OrderedDict对象
od = OrderedDict()
od['z'] = 1
od['e'] = 2
od['d'] = 3

# 按添加顺序遍历
for key in od:
    print(key, od[key])

# 从Python 3.8开始,可以使用reversed()
for key in reversed(od):
    print(key, od[key])

4. namedtuple

namedtuple生成可以使用名字来访问元素内容的元组子类。这比使用普通元组更加清晰,无需通过索引访问,可以使代码更易于阅读和维护。

from collections import namedtuple

# 创建一个namedtuple对象
Person = namedtuple('Person', ['name', 'age'])

# 实例化
p = Person(name="John", age=30)

# 通过名字访问
print(p.name)
print(p.age)

5. deque

deque(双端队列)是一种从头部和尾部都能快速增加和删除元素的容器。它提供了比list更高效的方法来插入和删除操作,适用于队列和广度优先树搜索等。

from collections import deque

# 创建一个deque对象
dq = deque(["a", "b", "c"])

# 在右侧添加元素
dq.append("d")

# 在左侧添加元素
dq.appendleft("e")

print(dq)

# 旋转队列
dq.rotate(2)
print(dq)

itertools

Python的itertools模块是Python标准库的一部分,提供了一系列用于构建迭代器的高效、优雅的工具。这些工具可以帮助你进行复杂的迭代操作,如组合数据、循环遍历、过滤数据等,而且都是以高效的方式实现的。

chain - 链接迭代器

chain函数可以用来链接多个可迭代对象,创建一个单一的迭代器。

import itertools

for item in itertools.chain([1, 2, 3], ['a', 'b', 'c']):
    print(item)
# 输出:
# 1
# 2
# 3
# a
# b
# c

count-计数无穷迭代器

用于创建一个简单的无限计数器。它会返回一个无尽的连续整数流,每次迭代时返回下一个整数。这个函数非常有用,特别是当你需要一个持续增加的计数器,或者在循环中需要一个无限序列时。

itertools.count的基本语法如下:

itertools.count(start=0, step=1)
  • start:计数的起始值,默认为0。
  • step:计数的步长,默认为1。步长可以是任何非零的数字,包括负数和浮点数。

返回值是一个迭代器,每次迭代返回当前的计数值,并按照指定的步长更新计数值。

示例1:基础示例

import itertools

# 创建一个从0开始的计数器
counter = itertools.count()

# 打印前5个数
for _ in range(5):
    print(next(counter))
    
# 输出:
# 0
# 1
# 2
# 3
# 4

这个示例演示了如何创建一个从0开始,步长为1的简单计数器,并打印前5个数。

示例2:自定义起始值和步长

import itertools

# 创建一个从10开始,步长为2的计数器
counter = itertools.count(start=10, step=2)

# 打印前5个数
for _ in range(5):
    print(next(counter))
    
# 输出:
# 10
# 12
# 14
# 16
# 18

在这个示例中,计数器从10开始,每次以2为步长递增。

示例3:使用负数和浮点数

import itertools

# 创建一个从-1开始,步长为-0.5的计数器
counter = itertools.count(start=-1, step=-0.5)

# 打印前5个数
for _ in range(5):
    print(next(counter))
    
# 输出:
# -1.0
# -1.5
# -2.0
# -2.5
# -3.0

这个示例展示了itertools.count支持负数和浮点数作为起始值和步长。

cycle - 循环迭代

cycle函数会无限循环给定的可迭代对象。注意,这会创建一个无限迭代器,所以你通常需要某种方式来中断循环。

counter = 0
for item in itertools.cycle(['a', 'b', 'c']):
    if counter > 6:
        break
    print(item)
    counter += 1
# 输出:
# a
# b
# c
# a
# b
# c
# a

islice - 迭代器切片

islice函数类似于列表的切片操作,但是用于迭代器。它可以让你获取迭代器的一个切片,而不需要将迭代器转换成列表。

result = itertools.islice(range(10), 2, 6)
for number in result:
    print(number)
# 输出:
# 2
# 3
# 4
# 5

product - 笛卡尔积

itertools.product是Python标准库中itertools模块提供的一个函数,用于生成输入可迭代对象的笛卡尔积。简而言之,它会生成所有可能的元素对组合,这些组合来自于提供给product的所有可迭代对象。

itertools.product的基本语法如下:

itertools.product(*iterables, repeat=1)
  • *iterables:一个或多个可迭代对象。
  • repeat:一个整数,指定重复可迭代对象的次数。默认值为1。

返回值是一个迭代器,生成从输入可迭代对象中取得的元素的笛卡尔积。

示例1:两个列表的笛卡尔积

import itertools

# 计算两个列表的笛卡尔积
for pair in itertools.product([1, 2], ['a', 'b']):
    print(pair)

# 输出:
# (1, 'a')
# (1, 'b')
# (2, 'a')
# (2, 'b')

示例2:使用repeat参数

import itertools

# 生成单个列表的元素组合,重复2次
for pair in itertools.product([1, 2], repeat=2):
    print(pair)

# 输出:
# (1, 1)
# (1, 2)
# (2, 1)
# (2, 2)

在这个例子中,repeat参数使得我们可以计算单个列表元素的所有可能组合。

示例3:多个列表的笛卡尔积

import itertools

# 计算三个列表的笛卡尔积
for combination in itertools.product([1, 2], ['a', 'b'], ['x', 'y']):
    print(combination)

# 输出:
# (1, 'a', 'x')
# (1, 'a', 'y')
# (1, 'b', 'x')
# (1, 'b', 'y')
# (2, 'a', 'x')
# (2, 'a', 'y')
# (2, 'b', 'x')
# (2, 'b', 'y')

permutations - 排列

permutations函数返回可迭代对象的所有可能的排列组合,长度由第二个参数指定。

for item in itertools.permutations('ABC', 2):
    print(''.join(item))
# 输出:
# AB
# AC
# BA
# BC
# CA
# CB

combinations - 组合

combinations函数返回可迭代对象的所有可能的组合,长度由第二个参数指定,与permutations不同的是,组合不考虑元素的顺序。

for item in itertools.combinations('ABC', 2):
    print(''.join(item))
# 输出:
# AB
# AC
# BC

combinations_with_replacement-可重复组合

用于创建一个迭代器,生成由输入可迭代对象中的元素构成的所有长度为n的组合序列,允许元素重复。这个函数扩展了传统组合的概念,允许在每个组合中多次使用相同的元素。

combinations_with_replacement函数的基本语法如下:

itertools.combinations_with_replacement(iterable, r)
  • iterable:要从中抽取组合的数据集,可以是列表、元组或任何序列对象。
  • r:组合的长度,即每个组合中应有的元素数量。

返回值是一个迭代器,生成从输入的可迭代对象中抽取的长度为r的组合,组合中的元素可以重复。

示例1:基础示例

import itertools

# 从列表[1, 2, 3]中生成所有长度为2的组合,允许元素重复
for combo in itertools.combinations_with_replacement([1, 2, 3], 2):
    print(combo)

# 输出:
# (1, 1)
# (1, 2)
# (1, 3)
# (2, 2)
# (2, 3)
# (3, 3)

这个示例生成了从列表[1, 2, 3]中抽取的所有长度为2的组合,包括那些包含重复元素的组合。

示例2:应用于字符串

import itertools

# 生成字符串'ABC'中所有长度为2的组合,允许元素重复
for combo in itertools.combinations_with_replacement('ABC', 2):
    print(''.join(combo))

# 输出:
# AA
# AB
# AC
# BB
# BC
# CC

这个示例演示了如何将combinations_with_replacement应用于字符串,生成所有可能的长度为2的组合,包括重复元素的组合。

groupby - 分组迭代

itertools.groupby函数是Python标准库itertools模块中的一个工具,用于对序列中连续的相同元素进行分组。它是处理迭代数据的强大工具,特别是当你需要根据某个条件将数据分组时。

groupby函数的基本语法如下:

itertools.groupby(iterable, key=None)
  • iterable:一个序列或任何可迭代对象。
  • key:一个函数,用于指定分组的条件。对于iterable中的每个元素,key函数会被调用以决定分组的键。如果不提供key,则直接使用元素本身作为分组的键。

groupby返回一个迭代器,其中的每个元素是一个元组(key, group),其中key是分组键,group是一个迭代器,包含了所有在当前分组中的元素。

注意

  • groupby仅对连续的相同元素进行分组。因此,在使用groupby之前,通常需要先将输入数据进行排序(除非数据已经是按照所需的分组键排序的)。

示例1:基础示例

from itertools import groupby

data = ['A', 'B', 'B', 'A', 'C', 'A', 'A', 'B']

for key, group in groupby(data):
    print(key, list(group))

# 输出:
# A ['A']
# B ['B', 'B']
# A ['A']
# C ['C']
# A ['A', 'A']
# B ['B']

示例2:使用key函数进行分组

假设我们有一组字典,需要根据字典中的某个键值对进行分组。

from itertools import groupby
from operator import itemgetter

data = [
    {'name': 'John', 'age': 35},
    {'name': 'Diana', 'age': 35},
    {'name': 'Mike', 'age': 32},
]

# 按照年龄分组
data.sort(key=itemgetter('age'))  # 首先按照年龄排序
for age, group in groupby(data, key=itemgetter('age')):
    print(age, list(group))

# 输出:
# 32 [{'name': 'Mike', 'age': 32}]
# 35 [{'name': 'John', 'age': 35}, {'name': 'Diana', 'age': 35}]

zip_longest-长拉链

用于将多个可迭代对象中的对应元素打包成一个个元组。与内置的zip函数不同,zip_longest会处理不等长的可迭代对象,直到所有的输入可迭代对象都被耗尽。对于较短的可迭代对象中缺失的元素,zip_longest允许你指定一个填充值。

itertools.zip_longest的基本语法如下:

itertools.zip_longest(*iterables, fillvalue=None)
  • *iterables:一个或多个可迭代对象。
  • fillvalue:可选参数,用于指定当某个可迭代对象先于其他对象耗尽时用于填充的值,默认为None

返回值是一个迭代器,每次迭代返回一个元组,包含了输入的每个可迭代对象中的对应元素。如果某个可迭代对象的元素已经耗尽,则使用fillvalue指定的值填充。

示例1:基础示例

from itertools import zip_longest

numbers = [1, 2, 3]
letters = ['a', 'b']

zipped = zip_longest(numbers, letters)

for item in zipped:
    print(item)

# 输出:
# (1, 'a')
# (2, 'b')
# (3, None)

在这个示例中,由于numbers列表比letters列表长,zip_longest使用None(默认的fillvalue)填充了缺失的元素。

示例2:指定填充值

from itertools import zip_longest

numbers = [1, 2, 3, 4]
letters = ['a', 'b']

zipped = zip_longest(numbers, letters, fillvalue='?')

for item in zipped:
    print(item)

# 输出:
# (1, 'a')
# (2, 'b')
# (3, '?')
# (4, '?')

通过指定fillvalue='?'zip_longestletters耗尽后用'?'填充缺失的元素。

math

Python提供了丰富的数学操作功能,主要通过内置的数学模块math和第三方库(如numpy)来实现。这里,我将介绍Python内置的math模块的基本使用方法,这个模块提供了许多数学运算函数,用于执行浮点数学运算。

导入math模块

在使用math模块之前,需要先导入它:

import math

常用数学函数

  1. 幂和对数函数

    • math.pow(x, y): 计算x的y次幂。
    • math.sqrt(x): 计算x的平方根。
    • math.exp(x): 计算e的x次幂。
    • math.log(x[, base]): 计算x的对数,默认为自然对数,可以指定底数base
  2. 三角函数

    • math.sin(x): 计算弧度x的正弦。
    • math.cos(x): 计算弧度x的余弦。
    • math.tan(x): 计算弧度x的正切。
    • math.asin(x): 计算x的反正弦,结果为弧度。
    • math.acos(x): 计算x的反余弦,结果为弧度。
    • math.atan(x): 计算x的反正切,结果为弧度。
  3. 角度和弧度转换

    • math.degrees(x): 将弧度x转换为角度。
    • math.radians(x): 将角度x转换为弧度。
  4. 双曲函数

    • math.sinh(x): 计算x的双曲正弦。
    • math.cosh(x): 计算x的双曲余弦。
    • math.tanh(x): 计算x的双曲正切。
  5. 特殊函数

    • math.erf(x): 计算x的误差函数。
    • math.gamma(x): 计算x的伽马函数。
  6. 常量

    • math.pi: 圆周率π。
    • math.e: 自然对数的底数e。

示例代码

以下是一些使用math模块函数的示例:

import math

# 计算平方根
print(math.sqrt(9))

# 计算4的3次幂
print(math.pow(4, 3))

# 将90度转换为弧度
print(math.radians(90))

# 计算sin(pi/2)
print(math.sin(math.pi / 2))

# 计算自然对数
print(math.log(math.e))