DevCN
菜单
全部文章快讯开发深度热点

Python 列表与字典:整理任务标签并避开浅拷贝陷阱

用任务标签计数练习列表遍历、字典累加和稳定排序,并通过一个可复现的嵌套列表示例理解赋值、浅拷贝与深拷贝。


本节目标

用任务标签计数练习列表遍历、字典累加和稳定排序,并通过一个可复现的嵌套列表示例理解赋值、浅拷贝与深拷贝。

知识与使用场景

列表适合保存一串任务,字典适合根据标签名查找计数。任务拥有多个标签时,可以把 tags 存成列表,再将任务本身表示为字典。这样的嵌套结构接近 JSON 数据,也适合后续写入文件。

计数时先明确统计对象:本节统计“标签出现次数”,所以同一个任务重复写两次 Python,也会被计为两次。若业务要统计带该标签的任务数,应先对每个任务的标签去重,再累计。

copied = tasks.copy() 只创建外层列表,内部任务字典仍然共享。直接赋值连外层都共享。需要独立修改整个嵌套结构时,可以考虑 deepcopy;它也有成本,不应为了心理上的保险对所有对象盲目深拷贝。

完整示例

from copy import deepcopy

tasks = [
    {"title": "练习循环", "tags": ["Python", "基础"]},
    {"title": "读取文件", "tags": ["Python", "文件"]},
]
counts = {}
for task in tasks:
    for tag in task["tags"]:
        counts[tag] = counts.get(tag, 0) + 1

print(sorted(counts.items(), key=lambda item: (-item[1], item[0])))
copied = tasks.copy()
copied[0]["tags"].append("复习")
print("复习" in tasks[0]["tags"])
independent = deepcopy(tasks)
independent[0]["title"] = "独立任务"
print(tasks[0]["title"])

预期结果

[('Python', 2), ('基础', 1), ('文件', 1)]
True
练习循环

运行与逐步理解

运行 lesson.py 后,首先查看计数结果。get 的默认值为 0,因此首次遇到标签时不需要先插入。排序键由两个部分组成:负计数实现出现次数降序,标签名实现同次数时的确定性排序。

这里标签名使用字符串自身的排序规则,不是中文拼音顺序。如果产品要求按拼音展示,需要单独定义排序策略。不要凭某次输出推断所有中文标签都会按读音排列。

随后向浅拷贝中的标签列表追加“复习”,原任务也能看到它,所以第二行输出 True。最后通过深拷贝修改标题,原任务标题保持不变。三个输出共同说明:是否隔离修改,要看你实际复制到了哪一层。

常见问题与边界

  • 把 append 的返回值赋回列表变量会得到 None;append 的作用是修改列表。
  • 字典直接访问缺失键会抛 KeyError,get 适合这里的默认零计数。
  • set 可以去重,但不能依赖其迭代顺序来展示固定结果。
  • 如果任务缺少 tags,本例会报错;实际导入时应先校验结构,再进入统计。

动手练习

给第一条任务增加一个重复的 Python 标签。分别计算“出现次数”和“涉及任务数”。

参考答案

出现次数中 Python 变为 3。若把内层循环改为 for tag in set(task["tags"]):,每条任务最多给同一标签计数一次,Python 涉及任务数仍为 2;最终输出继续排序即可保持可复现。

DISCUSSION

文章回复

0 条公开回复
未登录回复需要审核后公开
还没有回复,欢迎参与讨论。