Python 标准库详解

Python 标准库详解

引言

本篇文章将详细介绍Python中几个重要的标准库,这些库可以帮助开发者更加高效地编写代码。我们将逐一探讨time库、random库、collections库以及itertools库,通过具体示例加深理解。

第一部分:时间处理——time库

获取当前时间

Python的time库提供了多种方法来获取当前时间。例如,localtime()函数可以获取本地时间,而gmtime()则返回UTC时间。此外,ctime()函数可以直接返回格式化的本地时间字符串。

使用time库获取时间非常简单:

首先导入time库,然后调用相关函数即可。例如:

time库可以获取当前时间点,通过localtime()可以获得本地时间,gmtime()是UTC时间。我们知道全球有时区划分,北京时间比UTC时间早八个小时。要获得这些时间,我们先导入time库,然后直接调用localtimegmtime并打印输出。

时间戳与计时

time库还提供了获取时间戳的方法,如time()perf_counter()process_time()。其中time()返回自纪元以来的秒数,perf_counter()process_time()则返回相对时间戳。perf_counter()会记录sleep时间,而process_time()不会。

通过记录两个时间戳之间的差值,可以实现简单的计时功能。例如:

我们使用上述三个方法分别获得时间戳,打印它们。然后执行一段代码,并让程序暂停五秒钟,再次获得时间戳,查看两个时间戳之间的差异。可以看到t1非常大,因为其计时起点非常遥远;t2t3是随机取点的间隔,所以绝对值无实际意义。timeperf_counter方法计时相同,而process_time少了五秒,即sleep的时间。

格式化输出

time库支持格式化输出时间,可以通过strftime()函数自定义格式。例如:

设定格式后输出,如“2018年8月29日”。

此外,time.sleep()可以让程序暂停指定秒数,常用于控制程序执行节奏。

第二部分:随机数生成——random库

随机种子

random库生成的是伪随机数,这意味着如果使用相同的种子,将会得到相同的结果。如果不设置种子,默认以当前时间为种子。

例如:

random库所有方法导入,设置种子为10,生成随机浮点数,再设置种子为10,生成相同的随机浮点数。若不设定种子,则每次生成不同随机数,因为时间不同。

随机整数与浮点数

random库提供了多种生成随机整数和浮点数的方法:

  • randint(a, b):生成[a, b]之间的随机整数。
  • randrange(stop)randrange(start, stop[, step]):生成[0, stop)或[start, stop)之间的随机整数,后者可以指定步长。
  • random():生成[0.0, 1.0)之间的随机浮点数。
  • uniform(a, b):生成[a, b]之间的随机浮点数。

例如:

生成一到十之间的整数,生成零到十之间的整数(不含十),生成零到十之间步长为二的随机整数,生成零到一之间的浮点数,生成二点一到三点五之间的浮点数。

操作序列

random库还提供了对序列操作的方法:

  • choice(seq):从序列中随机选择一个元素。
  • choices(population, weights=None, *, cum_weights=None, k=1):从序列中随机选择k个元素,可以选择权重。
  • shuffle(x):随机打乱序列。
  • sample(population, k):从序列中随机选择k个不重复的元素。

例如:

从列表中随机选择一个元素,从字符串中随机选择一个字符,从列表中重复采样五次,对列表进行随机排列,随机选择三个元素。

概率分布

random库还支持生成符合特定概率分布的随机数,如正态分布、指数分布等。以正态分布为例,可以使用normalvariate(mu, sigma)函数。

例如:

生成符合零均值一标准差的正态分布随机数,生成一万个正态分布随机数并绘制直方图。

实际应用示例

微信红包分配

使用random库可以实现公平的微信红包分配。通过均匀分布确保每个人的期望金额相等。

定义一个函数接收红包金额和人数,前n-1人随机分配金额,最后一人获得剩余金额。确保每人期望金额相等。

验证码生成

生成四位由数字和大小写字母组成的验证码:

使用string.digitsstring.ascii_letters组合成字符集,从中随机选择四个字符。

第三部分:容器数据类型——collections库

具名元组

collections.namedtuple允许创建带字段名的元组。例如:

定义一个具名元组Point,包含xy字段,初始化后可以像普通元组一样使用,同时可以通过字段名访问元素。

计数器

Counter用于统计元素出现频率,类似于字典,但提供更多便捷功能。例如:

统计字符串和列表中各元素出现次数,提取最常见的两个元素,对计数器执行加减运算。

双向队列

deque支持高效的两端插入和删除操作。例如:

创建一个双向队列,从两端添加和删除元素。

第四部分:迭代器工具——itertools库

排列组合

itertools库提供了多种生成排列组合的方法,如product()permutations()combinations()combinations_with_replacement()。例如:

生成笛卡尔积、排列和组合。

拉链模式

zip()函数将多个序列按位置组合,形成元组。例如:

将三个序列组合成元组列表。

无穷迭代

itertools库还提供了几种无穷迭代的方法,如count()cycle()repeat()。例如:

生成从十开始的无穷计数器,循环输出字符,重复输出值。

其他迭代器

chain()将多个可迭代对象连接成一个大的迭代器,enumerate()为可迭代对象添加索引,groupby()按规则对可迭代对象分组。例如:

将两个列表连接成一个大的迭代器,为字符串添加索引,按长度对列表分组。

总结

本文详细介绍了Python中几个重要的标准库,包括time库、random库、collections库和itertools库。这些库不仅功能强大,而且使用简便,能够显著提高开发效率。通过具体示例,我们更好地理解了这些库的使用方法和应用场景。


习题

1. time 库可以用来做什么?

  • A. 获取当前时间
  • B. 格式化输出时间
  • C. 实现计时器功能
  • D. 以上全部

答案: D. 以上全部

2. time 库中获取当前时间戳的方法有哪些?

  • A. time()
  • B. perf_counter()
  • C. process_time()
  • D. 以上全部

答案: D. 以上全部

3. 关于时间戳的说法正确的是?

  • A. time() 返回自纪元以来的秒数
  • B. perf_counter() 随意取一个时间点到现在的间隔秒数
  • C. process_time() 不会记录 sleep 时间
  • D. 以上全部

答案: D. 以上全部

4. random 库提供的随机数是?

  • A. 真随机数
  • B. 伪随机数
  • C. 加密随机数
  • D. 不确定

答案: B. 伪随机数

5. random 库中生成随机整数的方法有哪些?

  • A. randint(a, b)
  • B. randrange(stop)
  • C. randrange(start, stop, step)
  • D. 以上全部

答案: D. 以上全部

6. random 库中生成随机浮点数的方法有哪些?

  • A. random()
  • B. uniform(a, b)
  • C. 以上全部
  • D. 以上都不是

答案: C. 以上全部

7. random 库中用于序列数据类型的随机函数有哪些?

  • A. choice(seq)
  • B. choices(seq, k)
  • C. shuffle(seq)
  • D. sample(seq, k)
  • E. 以上全部

答案: E. 以上全部

8. collections 库中提供的容器数据类型有哪些?

  • A. namedtuple
  • B. Counter
  • C. deque
  • D. 以上全部

答案: D. 以上全部

9. itertools 库中常用的迭代器函数有哪些?

  • A. product
  • B. permutations
  • C. combinations
  • D. zip
  • E. 以上全部

答案: E. 以上全部

10. itertools 库中用于无穷迭代的函数有哪些?

  • A. count
  • B. cycle
  • C. repeat
  • D. 以上全部
    答案: D. 以上全部

习题1:模拟三门问题

题目:
模拟经典的三门问题,使用Python中的random库进行随机选择,并使用numpy库计算均值。设定不打开门和打开门的概率分别为两个列表,进行10,000次测试,计算并输出两种情况下的均值。

答案:
如果不打开门的概率均值为0.500587,如果改变选择的概率均值为0.5014。

代码:
导入所需的库
import random
import numpy as np

设定不打开门和打开门的概率列表
prob_not_switch = [0, 1]
prob_switch = [1, 0]

进行10000次测试
results_not_switch = [random.choice(prob_not_switch) for _ in range(10000)]
results_switch = [random.choice(prob_switch) for _ in range(10000)]

计算均值
mean_not_switch = np.mean(results_not_switch)
mean_switch = np.mean(results_switch)

输出结果
print(“如果不打开门的概率均值为:”, mean_not_switch)
print(“如果改变选择的概率均值为:”, mean_switch)

习题2:求解24点问题

题目:
求解经典的24点问题,使用Python中的itertools库中的productpermutations函数进行组合排列计算。定义一个除法函数my_divide,并从加减乘除运算符中选择操作符进行计算。如果结果等于24,则返回操作步骤;否则返回无解。

答案:
使用排列组合方法得到的结果是近似解,例如:8 / (3 - 8 / 3) = 24.9599,使用暴力计算方法可能会得到“impossible”的结果,表示无法精确等于24。

代码:
导入所需库
import itertools
import time
from collections import OrderedDict

定义除法函数
def my_divide(x, y):
return x / y if y != 0 else ‘inf’

定义运算符列表
operators = [‘+’, ‘-’, ‘*’, ‘/’]

第一层循环进行三次操作
for ops in itertools.product(operators, repeat=3):
for nums in itertools.permutations([3, 3, 8, 8]):
expr = f’{nums[0]} {ops[0]} {nums[1]} {ops[1]} {nums[2]} {ops[2]} {nums[3]}’
try:
result = eval(expr)
if abs(result - 24) < 1e-6:
print(f"解为: {expr} = {result}")
break
except ZeroDivisionError:
continue
else:
continue
break
else:
print(“无解”)

暴力计算方法
def brute_force():
results = []
for ops in itertools.product(operators, repeat=3):
for nums in itertools.permutations([3, 3, 8, 8]):
for perm in itertools.permutations(nums):
expr = f’{perm[0]} {ops[0]} {perm[1]} {ops[1]} {perm[2]} {ops[2]} {perm[3]}’
try:
result = eval(expr)
if abs(result - 24) < 1e-6:
results.append((expr, result))
elif abs(result - 24) < 1e-2:
results.append((expr, result, “近似解”))
except ZeroDivisionError:
continue
return results

start_time = time.time()
brute_force_results = brute_force()
end_time = time.time()

for res in brute_force_results:
print(res)

print(f"暴力计算耗时: {end_time - start_time:.2f}秒")


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

六月五日

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值