AI学习笔记整理(76)——Python学习5

Python语言深度掌握

  • 语言核心,深入理解Python运行机制:深入理解Python对象模型、内存管理、GIL机制、解释器工作原理
  • 精通Python语法与高级特性‌:装饰器、元类、上下文管理器、生成器协程、异步编程(asyncio)等
  • 性能优化:代码性能分析、内存泄漏排查、C扩展开发
  • 熟练使用标准库与常用第三方库‌:如 requests、pandas、numpy、logging、collections 等。

Python requests

Requests 是一个用于发送 HTTP 请求的 Python 库,广泛应用于网络爬虫、API 调用等场景。它支持多种 HTTP 方法(如 GET、POST 等),并能较为友好地处理请求参数、头信息、Cookies 等。相比于 Python 标准库中的 urllib,requests 更加简洁和人性化,使得编写网络请求代码变得更加容易。

安装与验证

requests 是一个第三方库,需通过 pip 安装。为了确保成功,需正确处理网络代理、镜像源和权限问题。

bash 复制代码
pip install requests

1、创建一个虚拟环境:python -m venv myenv

2、激活虚拟环境:myenv\Scripts\activate

3、在虚拟环境中安装python包:pip install requests

4、导出虚拟环境的依赖:pip freeze > requirements.txt

5、在全局环境中安装依赖:pip install -r requirements.txt

发送 GET 请求

python 复制代码
import requests

# 基础 GET 请求
response = requests.get('https://httpbin.org/get')
print(f'状态码: {response.status_code}')
print(f'响应文本: {response.text[:200]}')  # 打印前200个字符

# 带参数的 GET 请求 (两种方式等效)
params = {'key1': 'value1', 'key2': 'value2'}
# 方式一:手动拼接 URL(不推荐)
# 方式二:使用 `params` 参数(推荐)
response = requests.get('https://httpbin.org/get', params=params)
print(f'最终请求 URL: {response.url}')  # 将显示包含参数的完整URL

发送 POST 请求

python 复制代码
import requests
import json

# 提交表单数据 (application/x-www-form-urlencoded)
form_data = {'username': 'admin', 'password': 'secret'}
response = requests.post('https://httpbin.org/post', data=form_data)
print(f'表单提交响应: {response.json()}')

# 提交 JSON 数据 (application/json)
json_data = {'title': 'foo', 'body': 'bar', 'userId': 1}
headers = {'Content-Type': 'application/json'}
response = requests.post('https://httpbin.org/post', json=json_data) # 更简洁的方式,headers 自动设置
# 等价于: response = requests.post('https://httpbin.org/post', data=json.dumps(json_data), headers=headers)
print(f'JSON提交响应: {response.json()}')

处理响应对象

python 复制代码
import requests

response = requests.get('https://api.github.com')

# 1. 状态码与原因
print(f'状态码: {response.status_code}')  # 例如 200, 404, 500
print(f'状态原因: {response.reason}')     # 例如 OK, Not Found

# 2. 响应头 (字典形式,不区分大小写)
print(f'服务器类型: {response.headers.get("Server")}')
print(f'内容类型: {response.headers["Content-Type"]}')

# 3. 响应内容 (根据类型选择解码方式)
# 文本内容
print(f'文本内容 (自动解码): {response.text[:100]}')
# 指定编码(如遇乱码)
response.encoding = 'gbk'  # 手动指定编码格式

# 二进制内容 (用于非文本文件,如图片)
image_content = response.content  # 二进制数据

# JSON 内容 (如果响应是JSON格式,requests 能自动解析为字典)
json_data = response.json()
print(f'GitHub API 返回的 JSON 键: {list(json_data.keys())[:5]}')

Python pandas

pandas 是一个基于 Python 的、开源的数据分析和数据处理库,它构建在 NumPy 之上,为处理结构化或表格化数据(如 Excel 表格、CSV 文件、SQL 数据库结果)提供了快速、灵活且表达力强的数据结构。它是进行数据清洗、转换、分析和建模的必备工具,尤其适合用于统计分析和机器学习的数据预处理阶段 。

其核心数据结构有二:

  • Series:一维数组,可以看作是一个带有标签的列表,标签即为索引。
  • DataFrame:二维表格型数据结构,是 pandas 中最常用的对象。可以将其理解为一个 Excel 工作表或 SQL 数据库表,它由行索引(index)、列索引(columns)和数据值组成,每一列的数据类型可以不同 。

安装与导入

通常使用 pip 进行安装:pip install pandas

数据读取与写入

pandas 支持读取多种格式的数据,最常用的是读取 Excel 和 CSV 文件 。

python 复制代码
import pandas as pd

# 读取 CSV 文件
df_csv = pd.read_csv('data.csv')

# 读取 Excel 文件, 需要安装 `openpyxl` 或 `xlrd` 引擎
df_excel = pd.read_excel('data.xlsx', sheet_name='Sheet1') 

# 将 DataFrame 写入到 CSV 或 Excel 文件
df_csv.to_csv('output.csv', index=False) # index=False 表示不写入行索引
df_excel.to_excel('output.xlsx', sheet_name='Result')

数据查看与基本信息

python 复制代码
# 在数据处理前,通常需要先了解数据的整体情况。
# 假设 df 是一个已加载的 DataFrame
print(df.head())       # 查看前5行
print(df.tail())       # 查看后5行
print(df.shape)        # 查看行数和列数
print(df.info())       # 查看列的数据类型和非空值统计
print(df.describe())   # 查看数值型列的统计摘要 (计数、均值、标准差、最小值、四分位数等)

数据筛选与操作

python 复制代码
# 选择列
single_column = df['column_name']  # 返回一个 Series
multiple_columns = df[['column_A', 'column_B']]  # 返回一个 DataFrame

# 选择行 (按索引标签或位置)
rows_by_label = df.loc[0:5]        # 选择索引标签为0到5的行
rows_by_position = df.iloc[0:5]    # 选择位置为0到4的行(前5行)

# 条件筛选
filtered_df = df[df['score'] > 60]  # 筛选出分数大于60的行

# 添加/删除列
df['new_column'] = df['column_A'] + df['column_B']  # 创建新列
df.drop(columns=['column_to_drop'], inplace=True)  # 删除列,inplace=True 表示直接修改原df

数据清洗技巧

python 复制代码
# 处理缺失值
print(df.isnull().sum())  # 统计每列的缺失值数量
df_cleaned = df.dropna()  # 删除包含缺失值的行
df_filled = df.fillna(0)  # 用0填充所有缺失值,也可以用列均值 df['column'].fillna(df['column'].mean())

# 处理重复值
duplicates = df.duplicated().sum()  # 统计重复行数量
df_unique = df.drop_duplicates()    # 删除重复行

# 更改数据类型
df['column_name'] = df['column_name'].astype('int')  # 转换为整数类型

# 重命名列
df.rename(columns={'old_name': 'new_name'}, inplace=True)

数据聚合与合并

python 复制代码
# 分组聚合
group_result = df.groupby('category_column')['value_column'].sum()
# 例如,按部门统计销售额总和
# 更复杂的聚合可以使用 `.agg()` 函数
agg_result = df.groupby('category').agg({'value1': 'mean', 'value2': 'max'})

# 合并多个 DataFrame (常用于合并多个表格)
df1 = pd.read_excel('sales_01.xlsx')
df2 = pd.read_excel('sales_02.xlsx')
df_merged = pd.concat([df1, df2], ignore_index=True) # 纵向堆叠(追加行)

# 横向合并,类似于 SQL JOIN
df_left = pd.DataFrame({'key': ['A', 'B', 'C'], 'value_left': [1, 2, 3]})
df_right = pd.DataFrame({'key': ['B', 'C', 'D'], 'value_right': [4, 5, 6]})
merged_df = pd.merge(df_left, df_right, on='key', how='inner') # 内连接

Python numpy

Python NumPy(Numerical Python)是Python生态系统中进行科学计算和数据分析的基石库。它提供了一个高性能的多维数组对象ndarray,以及用于处理这些数组的大量函数。NumPy的核心在于其高效的数组运算能力,这使得它在机器学习、图像处理、金融建模等领域不可或缺。

NumPy 核心:ndarray数组

ndarray是NumPy的灵魂。它是一个多维、同质的(所有元素类型相同)数据容器,支持高效的向量化运算。

python 复制代码
import numpy as np

# 从Python列表创建
arr1 = np.array([1, 2, 3, 4, 5])
print(arr1)  # 输出: [1 2 3 4 5]

# 创建指定形状的全0数组
zeros_arr = np.zeros((2, 3))  # 2行3列的二维数组
print(zeros_arr)
# 输出:
# [[0. 0. 0.]
#  [0. 0. 0.]]

# 创建指定形状的全1数组
ones_arr = np.ones((3, 2), dtype=int)  # 指定数据类型为int
print(ones_arr)
# 输出:
# [[1 1]
#  [1 1]
#  [1 1]]

# 创建等差数列数组
range_arr = np.arange(0, 10, 2)  # 从0开始,到10结束(不包含),步长为2
print(range_arr)  # 输出: [0 2 4 6 8]

# 创建线性间隔数组
lin_arr = np.linspace(0, 1, 5)  # 在0到1之间均匀生成5个数字
print(lin_arr)  # 输出: [0.   0.25 0.5  0.75 1.  ]

arr = np.array([[1, 2, 3], [4, 5, 6]])
print('数组维度 ndim:', arr.ndim)       # 输出: 2
print('数组形状 shape:', arr.shape)     # 输出: (2, 3)
print('元素总数 size:', arr.size)       # 输出: 6
print('元素数据类型 dtype:', arr.dtype)  # 输出: int64 (取决于系统)

arr = np.array([[10, 20, 30], [40, 50, 60], [70, 80, 90]])

# 索引单个元素
print(arr[0, 1])  # 第0行第1列,输出: 20

# 切片(行)
print(arr[1:])  # 获取第1行及之后的所有行
# 输出:
# [[40 50 60]
#  [70 80 90]]

# 切片(行列组合)
print(arr[:, :2])  # 所有行,但只取每行的前两列
# 输出:
# [[10 20]
#  [40 50]
#  [70 80]]

# 布尔索引
mask = arr > 50
print(mask)  # 输出布尔数组
# 输出:
# [[False False False]
#  [False False  True]
#  [ True  True  True]]
print(arr[mask])  # 输出满足条件的元素: [60 70 80 90]

NumPy 的核心运算:广播与向量化

NumPy的核心优势在于其向量化运算和广播机制,这使得我们可以避免使用低效的Python循环。

python 复制代码
#向量化运算
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
print('加法:', a + b)   # 输出: [5 7 9]
print('乘法:', a * b)   # 输出: [4 10 18]
print('平方:', a ** 2)  # 输出: [1 4 9]

#广播:广播是一种强大的机制,它允许NumPy在不同形状的数组之间执行算术运算。
# 标量与数组运算
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr + 10)  # 数组每个元素都加10
# 输出:
# [[11 12 13]
#  [14 15 16]]

# 不同形状数组间的运算(广播)
row = np.array([10, 20, 30])
print(arr + row)  # row被广播,加到arr的每一行上
# 输出:
# [[11 22 33]
#  [14 25 36]]

#聚合函数
arr = np.array([[1, 2], [3, 4], [5, 6]])
print('总和:', np.sum(arr))         # 输出: 21
print('每列均值:', np.mean(arr, axis=0))  # 沿着第0轴(行)聚合,求每列均值。输出: [3. 4.]
print('每行最大值:', np.max(arr, axis=1))  # 沿着第1轴(列)聚合,求每行最大值。输出: [2 4 6]
print('标准差:', np.std(arr))       # 输出: 1.707825127659933

#矩阵运算
# 矩阵乘法
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
print('矩阵乘法(使用@运算符):\n', A @ B)
# 输出:
# [[19 22]
#  [43 50]]

# 矩阵转置
print('A的转置:\n', A.T)
# 输出:
# [[1 3]
#  [2 4]]

与其他库的集成

NumPy数组是许多高级科学计算库(如Pandas、Scikit-learn、Matplotlib)的通用数据交换格式。Pandas的DataFrame和Series在底层大量使用NumPy数组,可以轻松地进行转换。

python 复制代码
import pandas as pd
# 将Pandas Series转换为NumPy数组
s = pd.Series([1, 2, 3])
np_array = s.values
print(type(np_array))  # 输出: <class 'numpy.ndarray'>

Python logging

Python的logging模块是标准库中用于生成应用程序运行日志的核心工具。它提供了一个灵活的事件记录系统,能够帮助开发者进行调试、监控和诊断。

logging模块的核心架构基于四个关键类,它们协同工作以完成日志信息的记录和输出。

logging模块的核心架构基于四个关键类,它们协同工作以完成日志信息的记录和输出。日志级别定义了事件的重要性,从低到高依次为:DEBUG、INFO、WARNING、ERROR、CRITICAL。Logger和Handler可以设置各自的级别,只有当日志事件的级别不低于二者的级别时,该日志才会被处理。

基础使用方法

python 复制代码
import logging

# 1. 创建记录器 (Logger)
logger = logging.getLogger(__name__)  # 通常以模块名命名,便于追溯来源[ref_3]
logger.setLevel(logging.DEBUG)  # 设置记录器级别

# 2. 创建控制台处理器 (Handler)
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)  # 处理器级别,可以不同于记录器级别

# 3. 创建格式器 (Formatter)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
console_handler.setFormatter(formatter)

# 4. 将处理器添加到记录器
logger.addHandler(console_handler)

# 5. 记录日志
logger.debug("这是一条调试信息,通常看不到,因为处理器级别是INFO")
logger.info("程序正常运行。")
logger.warning("出现潜在问题。")
logger.error("发生了一个错误。")
logger.critical("发生了一个严重错误,程序可能无法继续运行。")

高级配置:使用配置文件

对于复杂的生产环境,通过代码配置日志系统会显得笨重且难以维护。logging模块支持从字典或配置文件(如JSON、YAML、.conf)加载配置,这提供了极大的灵活性,且可以在不修改代码的情况下调整日志行为。

下面是一个使用字典配置的示例:

python 复制代码
import logging
import logging.config

LOGGING_CONFIG = {
    "version": 1,  # 配置字典版本号,必须为1
    "disable_existing_loggers": False,  # 不禁用已存在的记录器
    "formatters": {
        "detailed": {
            "format": "%(asctime)s - %(name)s - %(levelname)s - %(module)s:%(lineno)d - %(message)s"
        },
        "simple": {
            "format": "%(levelname)-8s - %(message)s"
        }
    },
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
            "level": "INFO",
            "formatter": "simple",
            "stream": "ext://sys.stdout"
        },
        "file": {
            "class": "logging.handlers.RotatingFileHandler",  # 使用轮转文件处理器,防止单个文件过大[ref_1]
            "level": "DEBUG",
            "formatter": "detailed",
            "filename": "app.log",
            "maxBytes": 10485760,  # 10MB
            "backupCount": 5,
            "encoding": "utf8"
        }
    },
    "loggers": {
        "__main__": {  # 为主模块配置
            "level": "DEBUG",
            "handlers": ["console", "file"]
        },
        "my_module": {  # 为特定模块配置
            "level": "INFO",
            "handlers": ["file"],
            "propagate": False  # 是否向上(根记录器)传播日志记录
        }
    },
    "root": {  # 根记录器的配置
        "level": "WARNING",
        "handlers": ["console"]
    }
}

# 应用配置
logging.config.dictConfig(LOGGING_CONFIG)

# 获取记录器并记录日志
logger = logging.getLogger(__name__)
logger.info("应用程序启动,日志系统已通过字典配置完成。")

多模块项目中的最佳实践

  • 使用 name 获取 Logger:这是最佳实践。__name__变量会反映模块的层次结构(如package.submodule),使得日志来源一目了然,也便于对不同模块进行差异化配置。
  • 区分库日志和应用日志:作为库开发者,不应直接配置Handler,而应只创建Logger。配置应由最终使用该库的应用程序来完成。这可以通过将库的Logger级别设置为WARNING及以上,或将propagate设为True(默认)让日志向上传播给应用级记录器处理。
  • 记录异常信息:使用logger.exception()方法或在记录错误时传入exc_info=True参数,可以自动捕获并记录异常的堆栈跟踪信息,这对于排查错误至关重要。
python 复制代码
# 在模块 mylib/processor.py 中
import logging
logger = logging.getLogger(__name__)  # Logger名称将为 'mylib.processor'

def process_data(data):
    try:
        # ... 处理逻辑
        logger.debug(f"正在处理数据: {data}")
        result = 1 / 0  # 故意制造一个除零错误
    except ZeroDivisionError:
        # 方式一:使用exception方法,会自动记录堆栈信息(级别为ERROR)
        logger.exception("处理数据时发生除零错误")
        # 方式二:等价于 logger.error('xxx', exc_info=True)
        # logger.error("处理数据时发生除零错误", exc_info=True)
        raise

工程化实践与注意事项

  • 敏感信息脱敏:日志中切忌记录密码、密钥、完整Token等敏感信息。在记录前应对此类数据进行处理或脱敏。
  • 考虑异步日志:对于I/O密集型(如写入网络或大文件)或高并发场景,同步日志可能成为性能瓶颈。可以考虑使用logging.handlers.QueueHandler和logging.handlers.QueueListener实现异步日志,或将日志输出到标准输出(stdout),由外部的日志收集系统(如Docker日志驱动、systemd-journald)处理。
  • 环境隔离配置:在不同环境(开发、测试、生产)中,日志的详细程度和输出目的地通常不同。可以通过环境变量来动态加载不同的日志配置文件。
  • 结构化日志:为便于后续使用ELK(Elasticsearch, Logstash, Kibana)等日志分析系统进行检索和分析,应输出结构化的日志(如JSON格式)。这可以通过自定义Formatter来实现。
  • 性能考量:logging模块本身是高性能的,因为级别检查非常快。但要避免在日志调用中执行昂贵的操作。例如,使用logger.debug("Result: %s", expensive_function())而不是logger.debug("Result: " + expensive_function())。前者只有在日志级别为DEBUG时才会调用expensive_function(),而后者在任何级别下都会先执行字符串拼接和函数调用。

Python collections

Python 的 collections 模块是标准库中用于提供高级数据容器的模块,它扩展了内置数据类型(如 list、tuple、dict、set)的功能,为特定场景提供了更高效、更易用的数据结构。

核心数据结构概览

collections 模块提供了一系列专用容器,其核心功能及替代关系如下表所示:

namedtuple

namedtuple 用于创建具有字段名的元组子类,它让元组中每个位置的意义变得清晰,可以通过属性访问而非索引。

python 复制代码
from collections import namedtuple

# 定义命名元组类型
Point = namedtuple('Point', ['x', 'y'])
Circle = namedtuple('Circle', ['x', 'y', 'radius'])

# 创建实例
p1 = Point(10, 20)
c1 = Circle(0, 0, 5)

# 通过属性访问
print(f"Point: x={p1.x}, y={p1.y}")  # 输出: Point: x=10, y=20
print(f"Circle center: ({c1.x}, {c1.y}), radius={c1.radius}")  # 输出: Circle center: (0, 0), radius=5

# 支持元组的所有操作
x, y = p1  # 解构赋值
print(f"Unpacked: {x}, {y}")  # 输出: Unpacked: 10, 20
print(f"Index access: p1[0] = {p1[0]}")  # 输出: Index access: p1[0] = 10

# _asdict()方法将命名元组转换为有序字典
print(p1._asdict())  # 输出: {'x': 10, 'y': 20}

deque

deque(双端队列)是列表的替代品,当需要在序列两端进行频繁的插入和删除操作时,其性能远优于列表(list),因为列表在头部操作的时间复杂度是 O(n),而 deque 在两端操作的时间复杂度是 O(1)。

python 复制代码
from collections import deque

# 创建双端队列
d = deque([1, 2, 3])
print(f"Initial deque: {d}")  # 输出: Initial deque: deque([1, 2, 3])

# 在右侧(尾部)追加元素
d.append(4)
d.append(5)
print(f"After append: {d}")  # 输出: After append: deque([1, 2, 3, 4, 5])

# 在左侧(头部)追加元素
d.appendleft(0)
print(f"After appendleft: {d}")  # 输出: After appendleft: deque([0, 1, 2, 3, 4, 5])

# 从右侧弹出元素
right_pop = d.pop()
print(f"Popped from right: {right_pop}, deque: {d}")  # 输出: Popped from right: 5, deque: deque([0, 1, 2, 3, 4])

# 从左侧弹出元素
left_pop = d.popleft()
print(f"Popped from left: {left_pop}, deque: {d}")  # 输出: Popped from left: 0, deque: deque([1, 2, 3, 4])

# 旋转操作:正数向右旋转,负数向左旋转
d.rotate(2)
print(f"After rotate(2): {d}")  # 输出: After rotate(2): deque([3, 4, 1, 2])

# 应用:实现固定长度队列(滑动窗口)
window = deque(maxlen=3)
for i in range(5):
    window.append(i)
    print(f"Current window: {list(window)}")
# 输出:
# Current window: [0]
# Current window: [0, 1]
# Current window: [0, 1, 2]
# Current window: [1, 2, 3]  # 达到最大长度后,新元素加入,最老的元素被自动挤出
# Current window: [2, 3, 4]

defaultdict

defaultdict 是 dict 的子类,它接受一个可调用对象(工厂函数)作为参数,当访问不存在的键时,会自动调用该工厂函数生成默认值,而不会抛出 KeyError。

python 复制代码
from collections import defaultdict

# 使用list作为默认工厂,常用于分组
group_by_first_letter = defaultdict(list)
words = ['apple', 'bat', 'bar', 'atom', 'book']

for word in words:
    group_by_first_letter[word[0]].append(word)

print(dict(group_by_first_letter))
# 输出: {'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book']}

# 使用int作为默认工厂,常用于计数(效果类似Counter,但更基础)
counts = defaultdict(int)
for char in "mississippi":
    counts[char] += 1  # 首次访问不存在的键时,int()返回0,然后加1
print(dict(counts))  # 输出: {'m': 1, 'i': 4, 's': 4, 'p': 2}

# 使用lambda自定义复杂默认值
default_scores = defaultdict(lambda: {'math': 0, 'english': 0})
scores = default_scores
scores['Alice']['math'] = 95
scores['Bob']['english'] = 88
print(scores['Alice'])  # 输出: {'math': 95, 'english': 0}
print(scores['Charlie'])  # 访问不存在的键,返回lambda定义的默认字典
# 输出: {'math': 0, 'english': 0}

Counter

Counter 是 dict 的子类,专门用于对可哈希对象进行计数。它提供了便捷的方法来统计频率、查找最常见元素等。

python 复制代码
from collections import Counter

# 从可迭代对象创建Counter
words = ['red', 'blue', 'red', 'green', 'blue', 'blue']
color_counts = Counter(words)
print(f"Color counts: {color_counts}")  # 输出: Color counts: Counter({'blue': 3, 'red': 2, 'green': 1})

# 从字符串创建(统计字符频率)
char_counts = Counter("abracadabra")
print(f"Char counts: {char_counts}")  # 输出: Char counts: Counter({'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1})

# 手动更新计数
color_counts.update(['red', 'yellow'])
print(f"After update: {color_counts}")  # 输出: After update: Counter({'blue': 3, 'red': 3, 'green': 1, 'yellow': 1})

# 获取最常见的n个元素
print(f"Top 2 colors: {color_counts.most_common(2)}")  # 输出: Top 2 colors: [('blue', 3), ('red', 3)]

# Counter支持数学运算(集合运算)
c1 = Counter(a=3, b=1)
c2 = Counter(a=1, b=2)
print(f"c1 + c2: {c1 + c2}")  # 加法: Counter({'a': 4, 'b': 3})
print(f"c1 - c2: {c1 - c2}")  # 减法(只保留正数计数): Counter({'a': 2})
print(f"c1 & c2: {c1 & c2}")  # 交集(取最小计数): Counter({'a': 1, 'b': 1})
print(f"c1 | c2: {c1 | c2}")  # 并集(取最大计数): Counter({'a': 3, 'b': 2})

OrderedDict 与 ChainMap

尽管 Python 3.7+ 的普通字典保持了插入顺序,但 OrderedDict 在比较相等性时考虑顺序(OrderedDict([('a', 1), ('b', 2)]) != OrderedDict([('b', 2), ('a', 1)])),并且有 move_to_end(key) 和 popitem(last=True/False) 等方法,适合实现 LRU 缓存等结构。

ChainMap 将多个字典逻辑链接成一个映射,查找时按顺序检查每个字典,直到找到键为止,非常适合管理具有优先级的多层配置。

python 复制代码
from collections import OrderedDict, ChainMap

# OrderedDict示例:保持插入顺序(Python 3.6+普通dict也有此特性,但OrderedDict提供额外方法)
od = OrderedDict()
od['z'] = 1
od['y'] = 2
od['x'] = 3
print(f"Keys in insertion order: {list(od.keys())}")  # 输出: ['z', 'y', 'x']
od.move_to_end('z')  # 将键'z'移动到末尾
print(f"After moving 'z' to end: {list(od.keys())}")  # 输出: ['y', 'x', 'z']

# ChainMap示例:多层配置查找
defaults = {'theme': 'light', 'language': 'en'}
user_prefs = {'theme': 'dark'}
system_env = {'language': 'zh-CN'}

# 创建ChainMap,查找顺序:user_prefs -> defaults -> system_env
# 但实际上,ChainMap构造时第一个参数是最高优先级,所以更常见的用法是:用户设置 > 环境变量 > 默认值
config = ChainMap(user_prefs, system_env, defaults) # 查找顺序:user_prefs -> system_env -> defaults

print(f"theme: {config['theme']}")  # 从user_prefs中找到 'dark' [ref_5]
print(f"language: {config['language']}")  # 从system_env中找到 'zh-CN' [ref_5]
print(f"non_existent: {config.get('non_existent', 'not found')}")  # 所有字典中都没有,返回默认值 'not found'
相关推荐
weixin_668898641 小时前
分词、词嵌入
人工智能·深度学习
李子琪。1 小时前
基于“产业-空间-社会”三重网络的传统工业城市现代化转型路径研究——以广西柳州市典型
java·人工智能·经验分享
m0_564876841 小时前
nano-vllm学习
学习·vllm
gaohongfeng11 小时前
cuda from 11.4 to 12.2 install readme
人工智能
LaughingZhu2 小时前
Product Hunt 每日热榜 | 2026-03-22
大数据·数据库·人工智能·经验分享·搜索引擎
无聊大侠hello world2 小时前
黑马大模型 RAG 与 Agent 实战学习笔记——智扫通 Agent 项目
笔记·学习
醉颜凉2 小时前
Seal^_^【送书活动第8期】——《ChatGLM3大模型本地化部署、应用开发与微调》
人工智能·职场和发展·送书活动·chatglm3大模型
进击的野人2 小时前
从AI“说人话”到“说结构话”:Spring AI结构化输出实战解析
人工智能·spring·ai编程
jay神2 小时前
基于深度学习的车辆识别收费管理系统
人工智能·深度学习·yolo·目标检测·毕业设计