欢迎光临
我们一直在努力

《超简单:用 Python 让 Excel 飞起来》读书笔记:2.3.3 元组和集合:不可改与自动去重

avatar

🔥
个人主页:
杨利杰YJlio

❄️
个人专栏:
《Sysinternals实战教程》
《Windows PowerShell 实战》
《WINDOWS教程》
《IOS教程》

《微信助手》
《锤子助手》
《Python》
《Kali Linux》

《那些年未解决的Windows疑难杂症》
🌟
让复杂的事情更简单,让重复的工作自动化

请添加图片描述

在这里插入图片描述


《超简单:用 Python 让 Excel 飞起来》读书笔记:2.3.3 元组 tuple 与集合 set,固定字段、自动去重与 Excel 自动化实战

  • 1. 2.3.3 元组和集合:不可改与自动去重
  • 2. 先搞清楚:tuple 和 set 解决的不是同一个问题
  • 3. 元组 tuple:适合保存固定字段和固定配置
    • 3.1 tuple 为什么要设计成不可修改?
    • 3.2 tuple 在 Excel 自动化里的常见用途
    • 3.3 tuple 不是为了替代 list
  • 4. 集合 set:自动去重,但不要依赖顺序
    • 4.1 set 的创建方式
    • 4.2 set 最适合解决哪些问题?
    • 4.3 set 的最大坑:无序
  • 5. Excel 自动化场景:用 set 做部门去重统计
    • 5.1 更贴近真实 Excel 的写法
    • 5.2 如果要保持原始顺序怎么办?
    • 5.3 一个常见错误:把 set 当成排序工具
  • 6. 什么时候用 tuple,什么时候用 set?
    • 6.1 我的选择口诀
    • 6.2 一个更完整的对比表
  • 7. Mermaid:tuple 与 set 的选择流程
  • 8. 常见问题与踩坑提醒
    • 8.1 为什么 tuple 不能修改?
    • 8.2 set 去重后顺序乱了,是不是 Bug?
    • 8.3 tuple 和 list 哪个更常用?
    • 8.4 set 能不能保存列表?
    • 8.5 空大括号是不是 set?
    • 8.6 set 去重会不会丢数据?
  • 9. 总结提升

1号标题图

1. 2.3.3 元组和集合:不可改与自动去重

  这一篇继续整理《超简单:用 Python 让 Excel 飞起来》中的基础数据结构内容。前面已经学过变量、数字、字符串、列表和字典,这一节补上两个容易被新手忽略,但在办公自动化里很实用的对象:tuple 元组和 set 集合。

  很多刚学 Python 的同学会有一个误区:觉得 list 已经能装数据了,那 tuple 和 set 好像可有可无。这个判断不够准确。list 解决的是“按顺序装数据”,tuple 解决的是“固定不变的数据”,set 解决的是“自动去重的数据”。 这三个对象不是谁替代谁,而是各有边界。

  这一节我不想把它写成语法表,而是放到 Excel 自动化场景里去理解:什么时候应该用 tuple 保存固定字段,什么时候应该用 set 对部门、姓名、工号、文件名做去重,什么时候又不能直接用 set,因为它会打乱原始顺序。

  这张图先展示了本节的核心关系:左边是不可修改的 tuple,右边是自动去重的 set。它不是单纯讲语法,而是在提醒我们:不同容器解决的是不同的数据管理问题。

请添加图片描述

  从图中可以看出,tuple 更像一个“锁起来的数据盒子”,适合放固定字段;set 更像一个“去重过滤器”,输入里可以有重复值,输出只保留唯一值。如果把 tuple 和 set 都当成 list 的变种,就很容易在真实脚本里选错数据结构。

#mermaid-svg-aJzaE2PLUzmOQ7S6{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-aJzaE2PLUzmOQ7S6 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-aJzaE2PLUzmOQ7S6 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-aJzaE2PLUzmOQ7S6 .error-icon{fill:#552222;}#mermaid-svg-aJzaE2PLUzmOQ7S6 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-aJzaE2PLUzmOQ7S6 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-aJzaE2PLUzmOQ7S6 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-aJzaE2PLUzmOQ7S6 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-aJzaE2PLUzmOQ7S6 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-aJzaE2PLUzmOQ7S6 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-aJzaE2PLUzmOQ7S6 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-aJzaE2PLUzmOQ7S6 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-aJzaE2PLUzmOQ7S6 .marker.cross{stroke:#333333;}#mermaid-svg-aJzaE2PLUzmOQ7S6 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-aJzaE2PLUzmOQ7S6 p{margin:0;}#mermaid-svg-aJzaE2PLUzmOQ7S6 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-aJzaE2PLUzmOQ7S6 .cluster-label text{fill:#333;}#mermaid-svg-aJzaE2PLUzmOQ7S6 .cluster-label span{color:#333;}#mermaid-svg-aJzaE2PLUzmOQ7S6 .cluster-label span p{background-color:transparent;}#mermaid-svg-aJzaE2PLUzmOQ7S6 .label text,#mermaid-svg-aJzaE2PLUzmOQ7S6 span{fill:#333;color:#333;}#mermaid-svg-aJzaE2PLUzmOQ7S6 .node rect,#mermaid-svg-aJzaE2PLUzmOQ7S6 .node circle,#mermaid-svg-aJzaE2PLUzmOQ7S6 .node ellipse,#mermaid-svg-aJzaE2PLUzmOQ7S6 .node polygon,#mermaid-svg-aJzaE2PLUzmOQ7S6 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-aJzaE2PLUzmOQ7S6 .rough-node .label text,#mermaid-svg-aJzaE2PLUzmOQ7S6 .node .label text,#mermaid-svg-aJzaE2PLUzmOQ7S6 .image-shape .label,#mermaid-svg-aJzaE2PLUzmOQ7S6 .icon-shape .label{text-anchor:middle;}#mermaid-svg-aJzaE2PLUzmOQ7S6 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-aJzaE2PLUzmOQ7S6 .rough-node .label,#mermaid-svg-aJzaE2PLUzmOQ7S6 .node .label,#mermaid-svg-aJzaE2PLUzmOQ7S6 .image-shape .label,#mermaid-svg-aJzaE2PLUzmOQ7S6 .icon-shape .label{text-align:center;}#mermaid-svg-aJzaE2PLUzmOQ7S6 .node.clickable{cursor:pointer;}#mermaid-svg-aJzaE2PLUzmOQ7S6 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-aJzaE2PLUzmOQ7S6 .arrowheadPath{fill:#333333;}#mermaid-svg-aJzaE2PLUzmOQ7S6 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-aJzaE2PLUzmOQ7S6 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-aJzaE2PLUzmOQ7S6 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-aJzaE2PLUzmOQ7S6 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-aJzaE2PLUzmOQ7S6 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-aJzaE2PLUzmOQ7S6 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-aJzaE2PLUzmOQ7S6 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-aJzaE2PLUzmOQ7S6 .cluster text{fill:#333;}#mermaid-svg-aJzaE2PLUzmOQ7S6 .cluster span{color:#333;}#mermaid-svg-aJzaE2PLUzmOQ7S6 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-aJzaE2PLUzmOQ7S6 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-aJzaE2PLUzmOQ7S6 rect.text{fill:none;stroke-width:0;}#mermaid-svg-aJzaE2PLUzmOQ7S6 .icon-shape,#mermaid-svg-aJzaE2PLUzmOQ7S6 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-aJzaE2PLUzmOQ7S6 .icon-shape p,#mermaid-svg-aJzaE2PLUzmOQ7S6 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-aJzaE2PLUzmOQ7S6 .icon-shape .label rect,#mermaid-svg-aJzaE2PLUzmOQ7S6 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-aJzaE2PLUzmOQ7S6 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-aJzaE2PLUzmOQ7S6 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-aJzaE2PLUzmOQ7S6 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

Python 容器选择

list 列表

tuple 元组

set 集合

dict 字典

按顺序保存,可增删改

固定字段,不希望被误改

自动去重,快速判断是否存在

键值映射,字段和值对应


2号标题图

2. 先搞清楚:tuple 和 set 解决的不是同一个问题

  我更建议这样记:tuple 管“不能乱改”,set 管“不能重复”。 这比单纯背“tuple 是元组,set 是集合”更有用。

  在 Excel 自动化里,数据经常有两种状态。一种是固定配置,比如表头字段、模板列名、固定的输出顺序;另一种是原始业务数据,比如部门、姓名、工号、项目编号,这些数据可能重复,需要筛选唯一值。前者适合 tuple,后者适合 set。

  比如一个报表模板要求固定字段顺序为“姓名、部门、金额、日期”,这组字段本质上是脚本规则,不应该在执行过程中被随便修改。这个时候用 tuple 比 list 更能表达意图。

required_columns = ("姓名", "部门", "金额", "日期")
print(required_columns)
print(type(required_columns))

  再比如从 Excel 里读取部门列,里面可能有很多重复部门。此时我们关心的是“到底有哪些部门”,而不是每个部门出现了多少次,这种场景用 set 就很直接。

departments = ["IT", "财务", "IT", "人事", "财务", "研发"]

unique_departments = set(departments)

print(unique_departments)
print(type(unique_departments))

  数据结构不是为了“写起来炫”,而是为了让数据用途更清楚。 如果这组数据创建之后不希望被改动,优先考虑 tuple;如果这组数据的重点是去重和成员判断,优先考虑 set;如果这组数据还要按顺序追加、删除、修改,继续使用 list 更合适。

  实战判断:写脚本前先问一句:这组数据是“规则”,还是“原始数据”?规则更适合稳定保存,原始数据更常需要清洗、去重和统计。


3号标题图

3. 元组 tuple:适合保存固定字段和固定配置

  元组 tuple 使用小括号 () 表示。它和列表有点像,都可以保存多个元素,但它最大的特点是:一旦创建,元素不能被修改。

fields = ("姓名", "部门", "金额")

print(fields)
print(type(fields))

  输出结果类似:

('姓名', '部门', '金额')
<class 'tuple'>

  这张图展示的是 tuple 的典型使用场景:姓名、部门、金额这类字段被放进一个固定容器中,并用锁的视觉表达强调“不可修改”。

请添加图片描述

  从图中可以看出,tuple 更适合保存那些不应该在脚本执行过程中被误改的数据。比如 Excel 模板字段、固定表头、固定配置项。如果这些字段被中途修改,后面的读取、写入、匹配就可能全部错位。

3.1 tuple 为什么要设计成不可修改?

  新手会觉得“不能改”很麻烦,但在工程脚本里,“不能改”反而是一种保护。比如你写一个 Excel 汇总脚本,字段顺序固定为:

headers = ("姓名", "部门", "金额", "日期")

  如果后续代码不小心写了:

headers[0] = "员工姓名"

  程序会直接报错:

TypeError: 'tuple' object does not support item assignment

  这类报错反而是好事,因为它能尽早暴露“不该修改却被修改”的问题。 如果用 list 保存固定字段,脚本可能不会报错,但结果已经偏了,这种问题更隐蔽。

3.2 tuple 在 Excel 自动化里的常见用途

  我一般会把 tuple 用在这些场景:

required_columns = ("姓名", "部门", "金额")
export_columns = ("部门", "人数", "总金额")
fixed_sheets = ("汇总表", "明细表", "异常数据")

  这些数据有一个共同点:它们是脚本的“规则”,不是运行过程中要不断改变的数据。规则越稳定,脚本越容易维护。

  例如检查 Excel 是否缺少必需字段时,可以这样写:

required_columns = ("姓名", "部门", "金额")
excel_columns = ["姓名", "部门", "日期"]

missing_columns = []

for col in required_columns:
if col not in excel_columns:
missing_columns.append(col)

print("缺少字段:", missing_columns)

  这里 required_columns 用 tuple 保存,是因为它代表模板要求,不应该被随意修改。missing_columns 用 list 保存,是因为它需要在循环过程中不断追加。

  这个例子能说明一个关键点:同一个脚本里可以同时使用 tuple 和 list,关键看数据用途。

3.3 tuple 不是为了替代 list

  tuple 的价值不是“比 list 高级”,而是表达“这组数据不应该变”。如果后续数据需要频繁追加、删除、修改,就应该继续使用 list。

# 固定字段,适合 tuple
required_columns = ("姓名", "部门", "金额")

# 动态收集异常数据,适合 list
error_rows = []

  不要为了显得专业,把所有列表都改成元组。 容器选错以后,代码后面的处理逻辑会更别扭。


4号标题图

4. 集合 set:自动去重,但不要依赖顺序

  集合 set 的重点非常明确:自动去重。 它不关心元素出现了几次,只关心元素是否存在。

depts = ["IT", "财务", "IT", "人事", "财务"]
unique_depts = set(depts)

print(unique_depts)

  输出结果可能是:

{'IT', '财务', '人事'}

  这里有两个重点。第一,重复的 IT 和 财务 被自动去掉了。第二,输出顺序不一定和原列表一致。

  这张图展示的是 set 的核心工作方式:输入中可能包含重复数据,经过集合处理后,输出只保留唯一元素,并且不强调原始顺序。

请添加图片描述

  从图中能看出,set 像一个自动过滤器,特别适合处理“重复部门、重复姓名、重复工号”这类办公数据。但也要注意,set 是无序的,不适合用来保存必须按 Excel 原始顺序处理的数据。

4.1 set 的创建方式

  可以直接用大括号 {} 创建集合:

s = {"IT", "财务", "IT", "人事"}
print(s)

  也可以把列表转换成集合:

depts = ["IT", "财务", "IT", "人事", "财务"]
unique_depts = set(depts)

print(unique_depts)

  第二种写法在 Excel 自动化里更常见,因为我们通常是先从 Excel 里读出一列数据,得到一个 list,然后再用 set 去重。

4.2 set 最适合解决哪些问题?

  set 适合解决这几类问题:

# 部门去重
unique_depts = set(depts)

# 工号去重
unique_ids = set(employee_ids)

# 文件名去重
unique_files = set(file_names)

  如果目标是“统计有哪些种类”“判断是否重复”“快速判断某个值是否出现过”,set 很合适。

  比如判断某个部门是否存在:

depts = ["IT", "财务", "人事", "研发"]
dept_set = set(depts)

if "IT" in dept_set:
print("存在 IT 部门")

  在数据量比较大时,用 set 做成员判断通常更适合。对于办公自动化来说,像“某个工号是否出现过”“某个文件是否已处理过”“某个部门是否在名单里”,都可以用这个思路。

4.3 set 的最大坑:无序

  set 不保证原始顺序。如果你把 Excel 的行数据直接转成 set,再写回 Excel,很可能发现顺序和原来不一样。

depts = ["IT", "财务", "IT", "人事"]
print(list(set(depts)))

  这段代码确实能去重,但顺序不一定稳定。对于“只要唯一值”的场景没问题;但对于“要保持原始顺序”的报表,就不够严谨。

  风险提醒:如果业务要求“按原 Excel 顺序输出去重结果”,不要直接使用 list(set(data))。

  如果要保留原始顺序,可以使用下面这种有序去重写法:

depts = ["IT", "财务", "IT", "人事", "财务"]

unique_depts = list(dict.fromkeys(depts))

print(unique_depts)

  输出结果会保留第一次出现的顺序:

['IT', '财务', '人事']

  这个写法在 Excel 自动化里非常实用,既能去重,又不会破坏原始业务顺序。


5号标题图

5. Excel 自动化场景:用 set 做部门去重统计

  讲语法只是第一层,真正有价值的是放进 Excel 自动化里。比如从 Excel 中读取一列“部门”,里面有很多重复值,现在要统计部门种类。

depts = ["IT", "财务", "IT", "人事", "财务", "研发"]

dept_types = set(depts)

print("部门种类数:", len(dept_types))
print("部门种类:", dept_types)

  输出结果类似:

部门种类数: 4
部门种类: {'研发', 'IT', '财务', '人事'}

  这张图展示了一个更完整的 Excel 去重统计流程:左边是原始部门列,中间通过 Python 处理,右边得到去重后的部门种类和统计结果。

请添加图片描述

  从图中能看出,set 在办公自动化里的价值并不是“语法好看”,而是可以快速把重复数据压缩成唯一集合。对于部门统计、人员名单去重、文件批处理去重,这个思路都能直接复用。

5.1 更贴近真实 Excel 的写法

  如果后面结合 pandas 读取 Excel,思路可以变成:

import pandas as pd

df = pd.read_excel("员工信息.xlsx")

depts = df["部门"].dropna().tolist()
unique_depts = set(depts)

print("部门种类数:", len(unique_depts))
print("部门种类:", unique_depts)

  这里我多加了一个 dropna(),是为了排除 Excel 空单元格。否则空值可能混进数据里,影响统计结果。

  这一段代码的处理链路是:Excel 表格 → 读取部门列 → 去掉空值 → 转成列表 → set 去重 → len() 统计数量。 看起来简单,但这就是很多办公自动化脚本的基本骨架。

5.2 如果要保持原始顺序怎么办?

  如果只是统计种类数,set 没问题;但如果要把去重后的部门写回 Excel,并且要求保持第一次出现的顺序,就不建议直接使用 set。

import pandas as pd

df = pd.read_excel("员工信息.xlsx")

depts = df["部门"].dropna().tolist()
unique_depts = list(dict.fromkeys(depts))

print(unique_depts)

  这段代码会保留 Excel 中部门第一次出现的顺序。对于后续生成“部门清单”“下拉选项”“汇总表目录”这类内容,比 list(set(depts)) 更稳。

  推荐做法:只统计唯一值数量,用 set;既要去重又要保留原始顺序,用 dict.fromkeys() 这一类有序去重写法。

5.3 一个常见错误:把 set 当成排序工具

  set 只能帮你去重,不负责排序。如果你希望输出时按字母、拼音或者指定业务顺序排列,需要额外处理。

result = sorted(set(depts))
print(result)

  如果是英文或数字,sorted() 很好理解;但如果是中文部门名,排序结果未必符合业务习惯。所以实际报表里更稳的做法是:先明确业务顺序,再按规则输出。


6号标题图

6. 什么时候用 tuple,什么时候用 set?

  学到这里,真正要掌握的不是“tuple 怎么写、set 怎么写”,而是什么时候该用谁。这比背语法更重要。

  这张图用流程方式展示了 tuple 和 set 的选择逻辑:先判断是不是要存一组数据,再判断是否需要修改,是否需要去重。

请添加图片描述

  从图中能看出,tuple 和 set 的适用范围其实很清晰。固定字段、不希望被误改,用 tuple;需要自动去重、判断唯一值,用 set。 如果既要保持顺序又要修改,那通常还是 list 更合适。

6.1 我的选择口诀

  我自己会这样记:

固定不改,用 tuple
重复太多,用 set
顺序处理,用 list
结构映射,用 dict

  这四句话基本可以覆盖 Python 办公自动化入门阶段大多数容器选择问题。

6.2 一个更完整的对比表

数据结构是否有序是否可修改是否自动去重典型用途
list 有序 可修改 不去重 文件列表、行数据、批量处理
tuple 有序 不可修改 不去重 固定字段、固定配置、固定表头
set 不强调顺序 可增删 自动去重 去重、成员判断、唯一值统计
dict 有序 可修改 key 唯一 字段和值映射、结构化行数据

  不要为了“显得专业”滥用数据结构。 在脚本里,用错容器比写法不优雅更麻烦。因为一旦数据结构选错,后面的处理逻辑也会跟着变复杂。


7号标题图

7. Mermaid:tuple 与 set 的选择流程

  为了让这个判断更容易复用,我把选择逻辑整理成一个流程图。以后写脚本前,可以先问自己:这组数据是否要修改?是否要去重?是否依赖顺序?

#mermaid-svg-l80cBOoIPPL9MKet{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-l80cBOoIPPL9MKet .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-l80cBOoIPPL9MKet .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-l80cBOoIPPL9MKet .error-icon{fill:#552222;}#mermaid-svg-l80cBOoIPPL9MKet .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-l80cBOoIPPL9MKet .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-l80cBOoIPPL9MKet .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-l80cBOoIPPL9MKet .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-l80cBOoIPPL9MKet .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-l80cBOoIPPL9MKet .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-l80cBOoIPPL9MKet .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-l80cBOoIPPL9MKet .marker{fill:#333333;stroke:#333333;}#mermaid-svg-l80cBOoIPPL9MKet .marker.cross{stroke:#333333;}#mermaid-svg-l80cBOoIPPL9MKet svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-l80cBOoIPPL9MKet p{margin:0;}#mermaid-svg-l80cBOoIPPL9MKet .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-l80cBOoIPPL9MKet .cluster-label text{fill:#333;}#mermaid-svg-l80cBOoIPPL9MKet .cluster-label span{color:#333;}#mermaid-svg-l80cBOoIPPL9MKet .cluster-label span p{background-color:transparent;}#mermaid-svg-l80cBOoIPPL9MKet .label text,#mermaid-svg-l80cBOoIPPL9MKet span{fill:#333;color:#333;}#mermaid-svg-l80cBOoIPPL9MKet .node rect,#mermaid-svg-l80cBOoIPPL9MKet .node circle,#mermaid-svg-l80cBOoIPPL9MKet .node ellipse,#mermaid-svg-l80cBOoIPPL9MKet .node polygon,#mermaid-svg-l80cBOoIPPL9MKet .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-l80cBOoIPPL9MKet .rough-node .label text,#mermaid-svg-l80cBOoIPPL9MKet .node .label text,#mermaid-svg-l80cBOoIPPL9MKet .image-shape .label,#mermaid-svg-l80cBOoIPPL9MKet .icon-shape .label{text-anchor:middle;}#mermaid-svg-l80cBOoIPPL9MKet .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-l80cBOoIPPL9MKet .rough-node .label,#mermaid-svg-l80cBOoIPPL9MKet .node .label,#mermaid-svg-l80cBOoIPPL9MKet .image-shape .label,#mermaid-svg-l80cBOoIPPL9MKet .icon-shape .label{text-align:center;}#mermaid-svg-l80cBOoIPPL9MKet .node.clickable{cursor:pointer;}#mermaid-svg-l80cBOoIPPL9MKet .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-l80cBOoIPPL9MKet .arrowheadPath{fill:#333333;}#mermaid-svg-l80cBOoIPPL9MKet .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-l80cBOoIPPL9MKet .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-l80cBOoIPPL9MKet .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-l80cBOoIPPL9MKet .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-l80cBOoIPPL9MKet .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-l80cBOoIPPL9MKet .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-l80cBOoIPPL9MKet .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-l80cBOoIPPL9MKet .cluster text{fill:#333;}#mermaid-svg-l80cBOoIPPL9MKet .cluster span{color:#333;}#mermaid-svg-l80cBOoIPPL9MKet div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-l80cBOoIPPL9MKet .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-l80cBOoIPPL9MKet rect.text{fill:none;stroke-width:0;}#mermaid-svg-l80cBOoIPPL9MKet .icon-shape,#mermaid-svg-l80cBOoIPPL9MKet .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-l80cBOoIPPL9MKet .icon-shape p,#mermaid-svg-l80cBOoIPPL9MKet .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-l80cBOoIPPL9MKet .icon-shape .label rect,#mermaid-svg-l80cBOoIPPL9MKet .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-l80cBOoIPPL9MKet .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-l80cBOoIPPL9MKet .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-l80cBOoIPPL9MKet :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

需要修改

不希望修改

需要去重

不需要去重

需要

不需要

准备保存一组数据

是否需要保持原始顺序?

后续是否需要修改?

list 列表

tuple 元组

是否需要去重?

set 集合

根据业务选择 list 或 dict

是否需要恢复顺序?

使用有序去重方案

直接使用 set

  这个流程图的核心不是让你死记,而是让你形成一个习惯:先想数据的用途,再选数据结构。 这才是 Python 自动化脚本越来越稳的关键。

  比如你要保存一份固定表头,重点是“不希望被误改”,就不要纠结,直接用 tuple。如果你要从一列部门数据里提取唯一部门,重点是“去重”,就用 set。如果你要既去重又保持 Excel 原始顺序,就不要直接使用 set,可以使用 dict.fromkeys()。


8号标题图

8. 常见问题与踩坑提醒

8.1 为什么 tuple 不能修改?

  因为 tuple 的设计目标之一就是保持稳定。如果你希望这组字段不被脚本中途误改,用 tuple 是合理的。如果你本来就想频繁增删改,那就不要用 tuple,直接用 list。

8.2 set 去重后顺序乱了,是不是 Bug?

  不是 Bug。set 本来就不强调原始顺序。如果业务逻辑依赖顺序,就不要直接用 set 输出结果。

8.3 tuple 和 list 哪个更常用?

  入门阶段 list 更常用,因为它灵活。但随着脚本复杂度提高,tuple 会在固定配置、固定字段、函数返回多个值等场景里变得很实用。

8.4 set 能不能保存列表?

  普通 list 不能直接放进 set,因为 list 是可变对象,不可哈希。这个细节入门阶段不必深挖,但要知道:set 更适合保存字符串、数字、元组这类稳定值。

# 可以放进 set
s1 = {"IT", "财务", "人事"}

# 不建议这样理解:列表不能作为 set 的元素
# s2 = {["IT", "财务"]}

8.5 空大括号是不是 set?

  这是一个新手很容易踩的点。空大括号 {} 创建的是字典,不是集合。

a = {}
print(type(a))

  输出结果是:

<class 'dict'>

  如果要创建空集合,应该使用 set():

b = set()
print(type(b))

  这个细节很小,但真实脚本里很容易因为空集合写错,导致后面方法调用异常。

8.6 set 去重会不会丢数据?

  会丢掉重复项,这是它的设计目标。问题在于:你到底是想“保留唯一值”,还是想“保留所有原始记录”。如果你要做明细表,就不能用 set 直接处理整行数据;如果你只是要部门清单,set 就合适。

  使用 set 前要先确认业务目标。去重是功能,也是风险。


9号标题图

9. 总结提升

  这一节我真正想记住的不是两个英文单词,而是它们背后的使用边界。tuple 的价值是稳定,set 的价值是去重。

  如果是固定字段、固定表头、固定配置,我会优先考虑 tuple。 这样可以避免后续代码误改关键规则,让脚本更稳定。

  如果是部门、姓名、工号、文件名这类可能重复的数据,我会优先考虑 set。 它能快速得到唯一值,非常适合做统计、校验和分类。

  但 set 不是万能去重方案。 只要业务要求保留原始顺序,就必须额外处理,不能简单地 list(set(data)) 了事。

  从 Excel 自动化角度看,学数据结构不是为了背语法,而是为了让脚本更可靠、更清晰、更容易维护。能根据数据用途选对容器,后面的批量处理、数据清洗、报表汇总都会顺很多。

  一句话收尾:tuple 用来保护固定规则,set 用来压缩重复数据;选对容器,脚本才不容易越写越乱。


请添加图片描述

🔝 返回顶部

点击回到顶部

赞(0)
未经允许不得转载:171主机测评 » 《超简单:用 Python 让 Excel 飞起来》读书笔记:2.3.3 元组和集合:不可改与自动去重
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址