跳到主要内容

Python的一些常用方法

Note

记录Python的一些常用方法的代码片段及其解析。

字符串基于UTF-8字节数切片

@staticmethod
def utf8_slice_safe(text, start_byte=0, end_byte=None):
"""安全地基于 UTF-8 字节数切片字符串"""
if not isinstance(text, str):
return text
utf8_bytes = text.encode('utf-8')
if end_byte is None:
end_byte = len(utf8_bytes)

# 确保不切分多字节字符
# 查找 start_byte 之前的完整字符边界
while start_byte > 0 and (utf8_bytes[start_byte] & 0xC0) == 0x80:
start_byte -= 1

# 查找 end_byte 之前的完整字符边界
while end_byte < len(utf8_bytes) and (utf8_bytes[end_byte] & 0xC0) == 0x80:
end_byte += 1

sliced_bytes = utf8_bytes[start_byte:end_byte]
return sliced_bytes.decode('utf-8', errors='ignore')

封装xlsxwriter方便写入excel

"""
封装 xlsxwriter 功能
支持单元格数据写入、样式设置、合并单元格等操作
"""
import base64
import xlsxwriter
from io import BytesIO
from typing import Union, Dict, Any, Optional, List, Tuple


class ExcelWriter:
"""Excel 写入器类,提供便捷的 Excel 文件生成功能"""

def __init__(self, bytes_data: BytesIO = None,
paper=9, mt=0, mb=0, print_scale=58,
margins: Union[None, dict] = None,
track_column_width: bool = True):
"""
初始化 Excel 写入器

# TODO: 设置默认样式( xlsxwriter.Workbook(filename, options), 通过options传入default_format_properties )

Args:
bytes_data: BytesIO 对象(可选)
paper: 纸张类型(默认9)
mt: 页眉边距(默认0)
mb: 页脚边距(默认0)
print_scale: 打印缩放比例(默认58)
margins: 页边距字典(可选)
track_column_width: 是否跟踪列宽以支持自动调整(默认True)
如果手动设置列宽,可设为False以减少资源开销
"""
self.file_data = bytes_data if bytes_data else BytesIO()
self.workbook = xlsxwriter.Workbook(self.file_data)
self.worksheets = {}
self.formats = {}
self.current_sheet = None
# 用于跟踪每个工作表每列的最大宽度
self.track_column_width = track_column_width
self.column_widths = {} if track_column_width else None
if margins is None:
margins = {'left': 0.2, 'right': 0.2, 'top': 0.8, 'bottom': 0.2}
self.paper = paper
self.mt = mt
self.mb = mb
self.print_scale = print_scale
self.margins = margins

def add_sheet(self, sheet_name: str = 'Sheet1') -> 'ExcelWriter':
"""
添加工作表

Args:
sheet_name: 工作表名称

Returns:
self,支持链式调用
"""
if sheet_name not in self.worksheets:
self.worksheets[sheet_name] = self.workbook.add_worksheet(sheet_name)
# 初始化该工作表的列宽跟踪(如果启用)
if self.track_column_width:
self.column_widths[sheet_name] = {}
self.worksheets[sheet_name].set_paper(self.paper)
self.worksheets[sheet_name].set_paper(self.paper)
self.worksheets[sheet_name].set_header(margin=self.mt)
self.worksheets[sheet_name].set_footer(margin=self.mb)
self.worksheets[sheet_name].set_margins(**self.margins)
self.worksheets[sheet_name].set_print_scale(self.print_scale)
self.current_sheet = self.worksheets[sheet_name]
return self

def select_sheet(self, sheet_name: str) -> 'ExcelWriter':
"""
切换到指定的工作表

Args:
sheet_name: 工作表名称

Returns:
self,支持链式调用
"""
if sheet_name in self.worksheets:
self.current_sheet = self.worksheets[sheet_name]
else:
raise ValueError(f"工作表 '{sheet_name}' 不存在")
return self

def create_format(self, format_name: str, **properties) -> 'ExcelWriter':
"""
创建并保存格式样式

Args:
format_name: 格式名称
**properties: 格式属性,支持所有 xlsxwriter 的格式属性

常用属性示例:
- bold: 粗体 (True/False)
- italic: 斜体 (True/False)
- font_size: 字体大小
- font_color: 字体颜色
- bg_color: 背景颜色
- align: 水平对齐 ('left', 'center', 'right')
- valign: 垂直对齐 ('top', 'vcenter', 'bottom')
- border: 边框样式 (0-13)
- num_format: 数字格式

Returns:
self,支持链式调用
"""
self.formats[format_name] = self.workbook.add_format(properties)
return self

def write_cell(self, row: int, col: int, data: Any,
format_name: Optional[str] = None) -> 'ExcelWriter':
"""
写入单个单元格

Args:
row: 行号(从0开始)
col: 列号(从0开始)
data: 要写入的数据
format_name: 格式名称(可选)

Returns:
self,支持链式调用
"""
if self.current_sheet is None:
self.add_sheet()

fmt = self.formats.get(format_name) if format_name else None
self.current_sheet.write(row, col, data, fmt)

# 更新列宽跟踪
self._update_column_width(col, data)

return self

def write_row(self, row: int, start_col: int, data: List[Any],
format_name: Optional[str] = None) -> 'ExcelWriter':
"""
写入一行数据

Args:
row: 行号(从0开始)
start_col: 起始列号(从0开始)
data: 数据列表
format_name: 格式名称(可选)

Returns:
self,支持链式调用
"""
if self.current_sheet is None:
self.add_sheet()

fmt = self.formats.get(format_name) if format_name else None
self.current_sheet.write_row(row, start_col, data, fmt)

# 更新每列的宽度跟踪
for i, cell_data in enumerate(data):
self._update_column_width(start_col + i, cell_data)

return self

def write_column(self, col: int, start_row: int, data: List[Any],
format_name: Optional[str] = None) -> 'ExcelWriter':
"""
写入一列数据

Args:
col: 列号(从0开始)
start_row: 起始行号(从0开始)
data: 数据列表
format_name: 格式名称(可选)

Returns:
self,支持链式调用
"""
if self.current_sheet is None:
self.add_sheet()

fmt = self.formats.get(format_name) if format_name else None
self.current_sheet.write_column(start_row, col, data, fmt)

# 更新该列的宽度跟踪(取最宽的)
for cell_data in data:
self._update_column_width(col, cell_data)

return self

def merge_range(self, first_row: int, first_col: int,
last_row: int, last_col: int, data: Any = '',
format_name: Optional[str] = None) -> 'ExcelWriter':
"""
合并单元格并写入数据

Args:
first_row: 起始行号(从0开始)
first_col: 起始列号(从0开始)
last_row: 结束行号(从0开始)
last_col: 结束列号(从0开始)
data: 要写入的数据
format_name: 格式名称(可选)

Returns:
self,支持链式调用
"""
if self.current_sheet is None:
self.add_sheet()

fmt = self.formats.get(format_name) if format_name else None
self.current_sheet.merge_range(first_row, first_col, last_row, last_col, data, fmt)
return self

def merge_range_string(self, range_string: str, data: Any = '',
format_name: Optional[str] = None) -> 'ExcelWriter':
"""
使用 Excel 范围字符串合并单元格

Args:
range_string: Excel 范围字符串(如 'A1:C3')
data: 要写入的数据
format_name: 格式名称(可选)

Returns:
self,支持链式调用
"""
if self.current_sheet is None:
self.add_sheet()

fmt = self.formats.get(format_name) if format_name else None
self.current_sheet.merge_range(range_string, data, fmt)
return self

def set_column_width(self, first_col: int, last_col: int, width: float) -> 'ExcelWriter':
"""
设置列宽

Args:
first_col: 起始列号(从0开始)
last_col: 结束列号(从0开始)
width: 列宽

Returns:
self,支持链式调用
"""
if self.current_sheet is None:
self.add_sheet()

self.current_sheet.set_column(first_col, last_col, width)
return self

def set_row_height(self, row: int, height: float) -> 'ExcelWriter':
"""
设置行高

Args:
row: 行号(从0开始)
height: 行高

Returns:
self,支持链式调用
"""
if self.current_sheet is None:
self.add_sheet()

self.current_sheet.set_row(row, height)
return self

def write_formula(self, row: int, col: int, formula: str,
format_name: Optional[str] = None) -> 'ExcelWriter':
"""
写入公式

Args:
row: 行号(从0开始)
col: 列号(从0开始)
formula: Excel 公式(如 '=SUM(A1:A10)')
format_name: 格式名称(可选)

Returns:
self,支持链式调用
"""
if self.current_sheet is None:
self.add_sheet()

fmt = self.formats.get(format_name) if format_name else None
self.current_sheet.write_formula(row, col, formula, fmt)
return self

def write_table(self, start_row: int, start_col: int,
data: List[List[Any]], headers: Optional[List[str]] = None,
header_format: Optional[str] = None,
data_format: Optional[str] = None) -> 'ExcelWriter':
"""
写入表格数据(带标题行)

Args:
start_row: 起始行号(从0开始)
start_col: 起始列号(从0开始)
data: 二维数据列表
headers: 表头列表(可选)
header_format: 表头格式名称(可选)
data_format: 数据格式名称(可选)

Returns:
self,支持链式调用
"""
if self.current_sheet is None:
self.add_sheet()

current_row = start_row

# 写入表头
if headers:
self.write_row(current_row, start_col, headers, header_format)
current_row += 1

# 写入数据
for row_data in data:
self.write_row(current_row, start_col, row_data, data_format)
current_row += 1

return self

def insert_image(self, row: int, col: int, image_path: str,
options: Optional[Dict[str, Any]] = None) -> 'ExcelWriter':
"""
插入图片

Args:
row: 行号(从0开始)
col: 列号(从0开始)
image_path: 图片文件路径
options: 图片选项(可选),如 {'x_scale': 0.5, 'y_scale': 0.5}

Returns:
self,支持链式调用
"""
if self.current_sheet is None:
self.add_sheet()

if options:
self.current_sheet.insert_image(row, col, image_path, options)
else:
self.current_sheet.insert_image(row, col, image_path)
return self

def freeze_panes(self, row: int, col: int) -> 'ExcelWriter':
"""
冻结窗格

Args:
row: 冻结的行数(从0开始)
col: 冻结的列数(从0开始)

Returns:
self,支持链式调用
"""
if self.current_sheet is None:
self.add_sheet()

self.current_sheet.freeze_panes(row, col)
return self

def autofilter(self, first_row: int, first_col: int,
last_row: int, last_col: int) -> 'ExcelWriter':
"""
设置自动筛选

Args:
first_row: 起始行号(从0开始)
first_col: 起始列号(从0开始)
last_row: 结束行号(从0开始)
last_col: 结束列号(从0开始)

Returns:
self,支持链式调用
"""
if self.current_sheet is None:
self.add_sheet()

self.current_sheet.autofilter(first_row, first_col, last_row, last_col)
return self

def _calculate_column_width(self, data: Any) -> float:
"""
计算单元格数据的显示宽度

Args:
data: 单元格数据

Returns:
float: 估算的列宽
"""
if data is None:
return 0

# 转换为字符串
text = str(data)

# 计算字符宽度(中文字符较宽,英文较窄)
width = 0
for char in text:
# 中文字符和全角字符宽度为2
if ord(char) > 127:
width += 2
else:
width += 1

# Excel 列宽基本单位转换,添加一些边距
return width * 1.2 + 2

def _update_column_width(self, col: int, data: Any):
"""
更新列宽跟踪(内部方法)

Args:
col: 列号
data: 单元格数据
"""
# 如果未启用列宽跟踪,直接返回
if not self.track_column_width:
return

# 获取当前工作表名称
sheet_name = None
for name, sheet in self.worksheets.items():
if sheet == self.current_sheet:
sheet_name = name
break

if sheet_name:
current_width = self._calculate_column_width(data)
# 更新该列的最大宽度
if col not in self.column_widths[sheet_name]:
self.column_widths[sheet_name][col] = current_width
else:
self.column_widths[sheet_name][col] = max(
self.column_widths[sheet_name][col],
current_width
)

def autofit_columns(self, sheet_name: Optional[str] = None,
min_width: float = 8, max_width: float = 50) -> 'ExcelWriter':
"""
自动调整列宽以适应内容

注意:需要在所有数据写入后、调用 read() 或 close() 之前调用此方法
注意:需要在初始化时启用 track_column_width=True(默认已启用)

Args:
sheet_name: 工作表名称(可选,默认为当前工作表)
min_width: 最小列宽(默认8)
max_width: 最大列宽(默认50)

Returns:
self,支持链式调用

Raises:
ValueError: 如果未启用列宽跟踪
"""
# 检查是否启用了列宽跟踪
if not self.track_column_width:
raise ValueError("列宽跟踪未启用。请在初始化时设置 track_column_width=True")

# 确定目标工作表
target_sheet = None
target_name = sheet_name

if sheet_name:
if sheet_name not in self.worksheets:
raise ValueError(f"工作表 '{sheet_name}' 不存在")
target_sheet = self.worksheets[sheet_name]
target_name = sheet_name
else:
if self.current_sheet is None:
raise ValueError("没有当前工作表")
target_sheet = self.current_sheet
# 找到当前工作表的名称
for name, sheet in self.worksheets.items():
if sheet == target_sheet:
target_name = name
break

# 应用列宽
if target_name in self.column_widths:
for col, width in self.column_widths[target_name].items():
# 限制在最小和最大宽度之间
adjusted_width = max(min_width, min(width, max_width))
target_sheet.set_column(col, col, adjusted_width)

return self

def autofit_all_columns(self, min_width: float = 8, max_width: float = 50) -> 'ExcelWriter':
"""
自动调整所有工作表的列宽

注意:需要在所有数据写入后、调用 read() 或 close() 之前调用此方法
注意:需要在初始化时启用 track_column_width=True(默认已启用)

Args:
min_width: 最小列宽(默认8)
max_width: 最大列宽(默认50)

Returns:
self,支持链式调用

Raises:
ValueError: 如果未启用列宽跟踪
"""
# 检查是否启用了列宽跟踪
if not self.track_column_width:
raise ValueError("列宽跟踪未启用。请在初始化时设置 track_column_width=True")

for sheet_name in self.worksheets.keys():
self.autofit_columns(sheet_name, min_width, max_width)

return self

def read(self):
"""
读取 Excel 文件的字节数据

注意:此方法会自动关闭 workbook(如果还未关闭)

Returns:
bytes: Excel 文件的字节数据
"""
# 步骤1:必须先关闭 workbook,数据才会真正写入到 BytesIO
self.workbook.close()

# 步骤2:重置文件指针到开头(close 后指针在末尾)
self.file_data.seek(0)

# 步骤3:读取所有数据
return self.file_data.read()

def read_base64(self):
# 步骤1:必须先关闭 workbook,数据才会真正写入到 BytesIO
self.workbook.close()

# 步骤2:重置文件指针到开头(close 后指针在末尾)
self.file_data.seek(0)

# 步骤3:读取所有数据
return base64.b64encode(self.file_data.read())

def close(self):
"""
关闭并保存 Excel 文件
"""
self.workbook.close()

def __enter__(self):
"""上下文管理器入口"""
return self

def __exit__(self, exc_type, exc_val, exc_tb):
"""上下文管理器退出,自动关闭文件"""
self.close()


# 使用示例
if __name__ == '__main__':
print("=== 示例1: 启用列宽跟踪(默认) ===")
b_data1 = BytesIO()
excel1 = ExcelWriter(bytes_data=b_data1) # track_column_width=True (默认)

excel1.create_format('header', bold=True, bg_color='#4472C4',
font_color='white', align='center', valign='vcenter', border=1)
excel1.add_sheet('自动列宽示例')
excel1.write_row(0, 0, ['产品名称', '销售数量', '单价'])
excel1.write_row(1, 0, ['这是一个123456很长的产品名称xxxxxxx', 100, 50.5])
excel1.write_row(2, 0, ['短名', 200, 30.8])

# 自动调整列宽
excel1.autofit_columns(min_width=10, max_width=40)

# 保存为文件
excel_data1 = excel1.read()
with open('example1_auto_width.xlsx', 'wb') as f:
f.write(excel_data1)
print('示例1完成:自动调整了列宽')
print(f'已保存为 example1_auto_width.xlsx,文件大小: {len(excel_data1)} bytes\n')

print("=== 示例2: 禁用列宽跟踪(手动设置列宽) ===")
b_data2 = BytesIO()
excel2 = ExcelWriter(bytes_data=b_data2, track_column_width=False) # 禁用跟踪

excel2.create_format('header', bold=True, bg_color='#4472C4',
font_color='white', align='center', valign='vcenter', border=1)
excel2.add_sheet('手动列宽示例')
excel2.write_row(0, 0, ['产品名称', '销售数量', '单价'])
excel2.write_row(1, 0, ['这是一个很长的产品名称', 100, 50.5])
excel2.write_row(2, 0, ['短名', 200, 30.8])

# 手动设置列宽
excel2.set_column_width(0, 0, 25)
excel2.set_column_width(1, 2, 12)

# 保存为文件
excel_data2 = excel2.read()
with open('example2_manual_width.xlsx', 'wb') as f:
f.write(excel_data2)
print('示例2完成:手动设置了列宽(节省了列宽跟踪的开销)')
print(f'已保存为 example2_manual_width.xlsx,文件大小: {len(excel_data2)} bytes\n')

print("=== 示例3: 尝试在禁用跟踪时调用 autofit(会报错) ===")
try:
b_data3 = BytesIO()
excel3 = ExcelWriter(bytes_data=b_data3, track_column_width=False)
excel3.add_sheet('测试')
excel3.write_row(0, 0, ['A', 'B', 'C'])
excel3.autofit_columns() # 这里会抛出错误
except ValueError as e:
print(f'预期的错误: {e}')

print("\n所有示例已完成!生成的文件:")
print(" - example1_auto_width.xlsx (使用自动列宽)")
print(" - example2_manual_width.xlsx (使用手动列宽)")


字典排序

# 原字典
d = {'b': 2, 'a': 1, 'c': 3}

# 按键排序(返回新字典)
sorted_dict = dict(sorted(d.items()))
# 结果: {'a': 1, 'b': 2, 'c': 3}

# 按键逆序
sorted_dict = dict(sorted(d.items(), reverse=True))
# 结果: {'c': 3, 'b': 2, 'a': 1}

2. 按值排序

# 按值排序
sorted_dict = dict(sorted(d.items(), key=lambda x: x[1]))
# 结果: {'a': 1, 'b': 2, 'c': 3}

# 按值逆序
sorted_dict = dict(sorted(d.items(), key=lambda x: x[1], reverse=True))
# 结果: {'c': 3, 'b': 2, 'a': 1}

# 使用operator.itemgetter
from operator import itemgetter
sorted_dict = dict(sorted(d.items(), key=itemgetter(1)))

# 对键进行处理之后排序,以下例子先按字符串再按数字排序
def parse_key(key):
parts = key.split('-')
return (parts[0], int(parts[1]))

sorted_dict = dict(sorted(d.items(), key=lambda x: parse_key(x[0])))
  • 高级排序用法
  1. 多级排序
# 复杂数据结构排序
students = {
'alice': {'grade': 85, 'age': 20},
'bob': {'grade': 90, 'age': 19},
'charlie': {'grade': 85, 'age': 21}
}

# 先按成绩降序,再按年龄升序
sorted_dict = dict(sorted(students.items(), key=lambda x: (-x[1]['grade'], x[1]['age'])))
  1. 自定义排序类
from functools import total_ordering

@total_ordering
class CustomKey:
def __init__(self, key):
self.parts = key.split('-')
self.name = self.parts[0]
self.num = int(self.parts[1]) if len(self.parts) > 1 else 0

def __lt__(self, other):
return (self.name, self.num) < (other.name, other.num)

def __eq__(self, other):
return (self.name, self.num) == (other.name, other.num)

d = {'b-2': 1, 'a-3': 2, 'b-1': 3}
sorted_dict = dict(sorted(d.items(), key=lambda x: CustomKey(x[0])))
  1. 使用heapq进行部分排序
import heapq

# 只需要前N个最小/最大值
d = {'a': 10, 'b': 5, 'c': 20, 'd': 1, 'e': 15}

# 获取值最小的3个
smallest_3 = dict(heapq.nsmallest(3, d.items(), key=lambda x: x[1]))

# 获取值最大的3个
largest_3 = dict(heapq.nlargest(3, d.items(), key=lambda x: x[1]))
  1. 稳定排序与不稳定排序
 # 稳定排序:相同值保持原有顺序
from collections import OrderedDict

d = OrderedDict([('a', 1), ('b', 2), ('c', 1), ('d', 2)])
stable_sorted = OrderedDict(sorted(d.items(), key=lambda x: x[1]))
  1. 条件排序
def conditional_sort(d, condition_func, sort_func):
"""根据条件选择性排序"""
to_sort = {k: v for k, v in d.items() if condition_func(k, v)}
not_sort = {k: v for k, v in d.items() if not condition_func(k, v)}

sorted_part = dict(sorted(to_sort.items(), key=sort_func))
return {**sorted_part, **not_sort}

d = {'apple-1': 10, 'banana-2': 5, 'cherry': 20}
result = conditional_sort(d,
lambda k, v: '-' in k, # 条件:键包含'-'
lambda x: int(x[0].split('-')[1])) # 排序函数
  1. 链式排序
from operator import itemgetter

# 多个排序条件链式应用
data = {'item1': (85, 'A'), 'item2': (90, 'B'), 'item3': (85, 'C')}

# 先按第一个元素降序,再按第二个元素升序
sorted_dict = dict(sorted(data.items(),
key=lambda x: (-x[1][0], x[1][1])))
  1. 性能优化排序
# 使用__slots__减少内存开销
class SortKey:
__slots__ = ['primary', 'secondary']

def __init__(self, key):
parts = key.split('-')
self.primary = parts[0]
self.secondary = int(parts[1]) if len(parts) > 1 else 0

# 预计算排序键避免重复计算
keys_cache = {k: SortKey(k) for k in d.keys()}
sorted_dict = dict(sorted(d.items(),
key=lambda x: (keys_cache[x[0]].primary,
keys_cache[x[0]].secondary)))
  1. 自然排序(处理数字字符串)
import re

def natural_sort_key(key):
"""自然排序:正确处理数字序列"""
return [int(text) if text.isdigit() else text.lower()
for text in re.split(r'(\d+)', key)]

d = {'item1': 1, 'item10': 2, 'item2': 3, 'item20': 4}
sorted_dict = dict(sorted(d.items(), key=lambda x: natural_sort_key(x[0])))
# 结果: item1, item2, item10, item20 (而不是 item1, item10, item2, item20)

简单二维矩阵

SimpleMatrix.py
from collections import defaultdict

class SimpleMatrix:
"""
简洁高效的二维索引数据结构
平衡了易用性和性能
"""

def __init__(self):
# 核心数据结构
self.data = {} # (row_key, col_key) -> value
self.rows = defaultdict(dict) # row_key -> {col_key: value}
self.cols = defaultdict(dict) # col_key -> {row_key: value}
self.row_keys = [] # 维护插入顺序
self.col_keys = []
self._row_set = set()
self._col_set = set()

def set(self, row_key, col_key, value):
"""设置数据"""
# 更新索引
if row_key not in self._row_set:
self.row_keys.append(row_key)
self._row_set.add(row_key)
if col_key not in self._col_set:
self.col_keys.append(col_key)
self._col_set.add(col_key)

# 存储数据到三个地方
self.data[(row_key, col_key)] = value
self.rows[row_key][col_key] = value
self.cols[col_key][row_key] = value

def get(self, row_key=None, col_key=None, default=None):
"""
灵活的获取接口
- get(row, col): 获取单个值
- get(row=row): 获取整行
- get(col=col): 获取整列
"""
if row_key is not None and col_key is not None:
# 获取单个值
return self.data.get((row_key, col_key), default)
elif row_key is not None:
# 获取整行
return dict(self.rows[row_key])
elif col_key is not None:
# 获取整列
return dict(self.cols[col_key])
else:
# 返回所有数据
return dict(self.data)

def get_row(self, row_key):
"""获取行数据"""
return dict(self.rows[row_key])

def get_col(self, col_key):
"""获取列数据"""
return dict(self.cols[col_key])

def delete(self, row_key=None, col_key=None):
"""删除数据"""
if row_key is not None and col_key is not None:
# 删除单个单元格
if (row_key, col_key) in self.data:
del self.data[(row_key, col_key)]
del self.rows[row_key][col_key]
del self.cols[col_key][row_key]
elif row_key is not None:
# 删除整行
for col_key in list(self.rows[row_key].keys()):
self.delete(row_key, col_key)
if row_key in self._row_set:
self.row_keys.remove(row_key)
self._row_set.remove(row_key)
elif col_key is not None:
# 删除整列
for row_key in list(self.cols[col_key].keys()):
self.delete(row_key, col_key)
if col_key in self._col_set:
self.col_keys.remove(col_key)
self._col_set.remove(col_key)

def to_list(self):
"""转换为二维列表"""
result = []
for row_key in self.row_keys:
row = []
for col_key in self.col_keys:
row.append(self.data.get((row_key, col_key), None))
result.append(row)
return result

def __repr__(self):
return f"SimpleMatrix(rows={len(self.row_keys)}, cols={len(self.col_keys)}, cells={len(self.data)})"