先扯点实在的。你写Python写了两三周变量、分支、循环都会了但一到真正处理数据就卡住手里有几百个用户ID要查重有一堆键值对要统计有几段文本要对比差异——这时候你才发现光靠单个变量根本没法干活。Python里的序列、字典、集合就是专门解决这类问题的第一梯队工具也是入门阶段最值得花时间吃透的三块内容。这篇继续咱们的Python入门系列我用最容易理解的方式把列表、元组、字典、集合一次讲明白包括它们的底层逻辑、常用操作和实战中会踩的坑。适合刚学完流程控制、想开始写点真实小脚本的入门读者也可以当作复习材料快速过一遍。1. 数据的容器思维序列、字典、集合到底在解决什么问题1.1 为什么学完语法就要立刻学容器很多人学编程有个误区觉得语法学完了就能写程序了。实际上程序处理的核心对象永远是数据而数据几乎不会是孤零零的一个值。回想一下你写过的练习判断一个数是不是质数、打印九九乘法表、计算斐波那契数列这些题目里数据量都很小几个变量就够用了。但真实场景完全不是这样。我举个例子你爬了一个网页拿到500条用户评论现在要统计每条评论里出现频率最高的词。你不可能写500个变量去存。你需要一种方式把“一坨数据”装进一个变量里然后对这个整体做操作。这就是容器的价值。Python官方文档里序列、字典、集合这几种类型统称“内置类型”直白点说就是语言自带的数据容器。序列的典型代表是字符串、列表、元组字典是键值对的映射容器集合则专注于去重和数学上的集合运算。三者承担的角色天然不同序列管“顺序”字典管“查找”集合管“关系”。把这句话刻在脑子里后面所有操作都不会迷路。1.2 用生活场景理解三类容器的差异为了把抽象概念落地我用三个生活物件做类比这套类比我在教新人的时候反复用效果一直不错。序列像是书橱里的书。书有第一本、第二本、第三本你可以按位置取第几本也可以从中间抽一截出来看可以往中间插一本也可以把某一本换掉。你关心的是“排列顺序”和“位置”。Python里的列表就是这样一个能改的书橱元组则像是封了塑封的书不能换不能插但读起来很快。字典像是学生档案柜。每个抽屉外面贴着学号里面放着对应的信息。你不需要知道“第几号抽屉”在哪个位置你只需要喊出学号档案管理员直接带你到对应抽屉前面。这就是“按键取值”查找效率非常高数据量越大优势越明显。集合像是景点的门票核销系统。它只关心一件事某个游客来没来过。同一张身份证号不会重复入园你也没法说“请把第三位游客给我看看”因为集合里没有顺序。它擅长的是判断“在不在里面”“这批人和那批人重了多少”。理解了这三个定位你再去看官方文档里那些方法列表就不会觉得枯燥了——每种容器的方法本质上都是在回答你“想对这个整体数据做什么”。2. 序列三兄弟字符串、列表、元组的使用细节2.1 列表是有序序列吗——“有序”的真实含义先回答新人问得最多的问题列表到底是不是有序序列答案是肯定的但要分清这里的“有序”是什么意思。列表的“有序”指的是元素按照你插入的顺序被保存并且每一个元素都有确定的下标位置而不是说列表会自动把元素从小到大排序。我来演示一下这个区别nums [5, 2, 8, 1] print(nums[0]) # 输出5说明位置是确定的 print(sorted(nums)) # 输出[1, 2, 5, 8]sorted返回新列表完成排序 print(nums) # 输出[5, 2, 8, 1]原列表顺序没变初次接触的人经常在这上面犯迷糊列表不是“有序”的吗怎么sort一下才变有序我建议你把“有序”理解成“有顺序”而不是“已排序”。列表负责稳定地记住顺序至于排序那是对数据的一种操作得你主动调用方法或函数去做。字符串也是序列它内部的每个字符同样有位置。元组也类似。所以当你听到“序列类型支持索引、切片、加和、乘、成员判断”这些话时意味着字符串、列表、元组三兄弟共享一套操作逻辑。这也是为什么学Python入门不推荐跳过元组直接学字典——序列的通用规律搞明白了三个类型一次性拿下。2.2 可变与不可变序列的核心分水岭Python序列要分成可变和不可变两大类这个属性决定了你能对数据做什么操作也决定了它能不能被放进字典当键、放进集合当元素。类型是否可变典型场景能不能当字典键字符串不可变文本处理、拼接、格式化可以列表可变动态增删数据、按位置存取不可以元组不可变定长记录、函数多返回值可以元素也得可哈希为什么可变性这么重要因为Python里字典和集合依靠“哈希值”来定位数据而哈希值是由内容算出来的。如果内容可以变哈希值就得跟着变存进去之后你再改它字典就找不到它了。所以Python干脆规定只有不可变类型数字、字符串、元组才能当字典键或集合元素。实用上的影响是你想用一个坐标点x, y当字典的键用列表表示坐标会报错写成元组就没事。代码对比一下# 错误示范 point1 [1, 2] # d {point1: 位置A} # TypeError: unhashable type: list # 正确做法 point2 (1, 2) d {point2: 位置A} print(d[(1, 2)]) # 输出“位置A”这个知识点看起来细但在实际编码中经常成为拦路虎。入门阶段只要记住如果你希望一块数据能作为“标签”去查另外的内容就把它弄成元组而不是列表。2.3 序列通用操作与切片避坑既然说序列共享一套操作我列几个最高频的通用操作并演示它们在三类序列上的表现s python lst [3, 1, 4, 1, 5] tup (10, 20, 30) # 长度、最大值、最小值、成员判断 print(len(s)) # 6 print(max(lst)) # 5 print(30 in tup) # True # 切片起始:结束:步长结束位置取不到 print(s[0:3]) # pyt print(lst[::-1]) # [5, 1, 4, 1, 3] 反转 print(tup[:2]) # (10, 20) # 拼接与重复 print([1, 2] [3]) # [1, 2, 3] print(ab * 2) # abab切片这套规则值得单独说一下因为入门阶段报错和不达预期的很大一部分来自这里。第一切片的结束位置是取不到的s[0:3]只有索引0、1、2三个元素。第二切片可以越界Python不会报错比如s[0:999]只是返回整个字符串这一点和用下标直接访问不一样——用lst[10]访问不存在的下标会直接抛IndexError但lst[0:10]安全返回。第三如果你发现切片结果不对劲先检查步长是正还是负默认是正1从前往后切要倒着取必须写[::-1]或明确给负步长。我实际写脚本时切片最常用的三个场景就是去末尾data[:-1]、反转data[::-1]、分段取数data[::2]取偶数位置。这些写在数据处理脚本里非常顺手。3. 字典打通键值对告别“用列表硬查”的笨办法3.1 字典的基本操作全景字典在Python入门阶段的核心价值就是给你一种“按名字找内容”的查找方式而不是“按位置翻内容”。建立一个字典的方式很灵活# 方式一花括号 info {name: 张三, age: 25, city: 北京} # 方式二dict()函数 info2 dict(name李四, age30) # 方式三从键值对序列转 info3 dict([(name, 王五), (age, 28)])增删改查四个基础操作覆盖90%的日常需求info {name: 张三, age: 25} # 增直接给不存在的键赋值 info[city] 北京 # 改给已存在的键赋值 info[age] 26 # 查用方括号或get方法 print(info[name]) # 张三 print(info.get(phone)) # None键不存在返回None而不是报错 print(info.get(phone, 未填写)) # 未填写可指定默认值 # 删pop弹出并返回del直接删除 age info.pop(age) print(age) # 26 del info[city]这里最值得养成习惯的是get()方法。新手图省事普遍直接用info[key]问题是键不存在时程序直接崩溃。在真实的脚本里你经常面对的是“这个键可能有也可能没有”的数据比如JSON接口返回的字段。用info.get(key, 默认值)就能优雅处理。我再补一个高频组合判断键是否存在用if name in info记住字典的in判断的是键不是值。批量更新字典用update()方法它能把另一个字典或键值对一次性合入当前字典这在合并配置项时非常实用config {debug: True, port: 8080} new_config {port: 9090, workers: 4} config.update(new_config) print(config) # {debug: True, port: 9090, workers: 4}3.2 字典的遍历与推导式数据量小的时候怎么取都能凑合数据量一上来遍历字典变成常规操作。Python提供了三种遍历视角info {name: 张三, age: 25, city: 北京} # 遍历键默认行为 for key in info: print(key) # 遍历键值对 for key, value in info.items(): print(key, value) # 只遍历值 for value in info.values(): print(value)items()是最常用的因为它一次性把键和值都给你避免了在循环体里再写一次info[key]去取值。性能上遍历键再查值会多一次哈希查找虽然差距微乎其微但写items()语义更清晰。字典推导式是入门阶段容易忽略但非常提效的语法。它和列表推导式长得像只是用花括号包起来并且写“键: 值”# 把列表变成字典元素作为键平方作为值 nums [1, 2, 3, 4] squares {n: n ** 2 for n in nums} print(squares) # {1: 1, 2: 4, 3: 9, 4: 4} # 过滤出符合条件的键值对 scores {语文: 88, 数学: 95, 英语: 72} passed {subject: score for subject, score in scores.items() if score 80} print(passed) # {语文: 88, 数学: 95}3.3 字典的常见坑位与进阶技巧字典这部分有几个坑几乎每个初学者都会踩我集中列出来。第一个坑键必须是不可变类型。前面已经讲过列表不能当键但新手很容易在微信昵称、临时数据里犯这个错。解法就是把列表转成元组。第二个坑{ }创建的是空字典不是空集合。想创建空集合必须用set()。这一点放在集合章节详细说。第三个坑键重复时后赋值的覆盖前面。这其实不是坑是设计但新手经常在循环构建字典时发现数据变少往往就是键被覆盖了。如果你需要“一个键对应多个值”可以配合列表from collections import defaultdict groups defaultdict(list) groups[甲组].append(张三) groups[甲组].append(李四) groups[乙组].append(王五) print(groups) # defaultdict(class list, {甲组: [张三, 李四], 乙组: [王五]})defaultdict是collections模块里的实用工具特点是访问不存在的键时不会再抛KeyError而是自动创建一个默认值容器。上面例子中默认值是空列表所以直接append就行。如果你不想引第三方其实它是标准库也可以用dict.setdefaultgroups {} groups.setdefault(甲组, []).append(张三)这两招在处理“分组”“归类”“统计”类需求时极其好用建议入门阶段就记下来。4. 集合自动去重和集合运算数据处理省下的力气4.1 集合的建立与去重实战集合最朴素的用途就是去重把可哈希的元素丢进集合重复的会自动消失。建立一个集合同样有几种写法# 正确set()函数传入序列 bag set([1, 2, 2, 3, 3, 3]) print(bag) # {1, 2, 3} # 正确直接写花括号内容 bag2 {1, 2, 3} # 错误空花括号是字典 empty {} print(type(empty)) # class dict # 正确空集合要这样 empty_set set() print(type(empty_set)) # class set去重的实际场景太常见了我随便举几个统计一篇文章里出现了多少个不同的词从用户ID列表里去掉重复ID从日志文件里提取出现过的IP集合。代码都是一行搞定user_ids [101, 102, 101, 103, 102, 104] unique_ids list(set(user_ids)) # 注意这样得到的列表顺序是不确定的这里要提醒一个新手经常困惑的现象集合去重后顺序可能和原来不一样。因为集合内部使用哈希表存储它只负责快速判断“在不在”不负责维持插入顺序。如果你既想去重又要保持原顺序可以使用一个小技巧user_ids [101, 102, 101, 103, 102, 104] unique_ids list(dict.fromkeys(user_ids)) print(unique_ids) # [101, 102, 103, 104]原理是利用字典“键不重复且插入顺序被保留”的特性。这个技巧在Python 3.7里是稳定有效的建议写进你的工具箱。4.2 交并差补四种运算如果说去重是集合的“甜点”那集合运算才是它的“主菜”。四个操作是必须掌握的并集两拨数据合起来有多少要素符号|交集两边共有的内容符号差集在前者但不在后者的内容符号-对称差集只属于其中一边的内容符号^直接上代码a {张, 李, 王} b {李, 赵} print(a | b) # {张, 李, 王, 赵} 并集 print(a b) # {李} 交集 print(a - b) # {张, 王} 差集 print(a ^ b) # {张, 王, 赵} 对称差集符号记不住的话也有对应的方法名union()、intersection()、difference()、symmetric_difference()。我个人写代码时习惯用符号因为简洁但做教学时会强调方法名因为含义更明确。集合还有两个判断关系的常用方法issubset()判断是否子集isdisjoint()判断是否完全没有交集。x {1, 2} y {1, 2, 3, 4} print(x.issubset(y)) # Truex是y的子集 print({1}.isdisjoint({2})) # True没有共同元素4.3 集合运算的实战场景光讲语法不提用法等于白学。我挑几个典型的应用场景你看看这些运算落到真实数据上有多顺手。场景一统计两个社交账号的共同好友。把两个账号的好友ID各转成一个集合交集结果就是共同好友。my_friends {张三, 李四, 王五} other_friends {李四, 陈六} common my_friends other_friends print(common) # {李四}场景二检查一批规则中有多少重叠的标签。比如你在做文本分类一篇文章打了“科技”和“互联网”两个标签另一篇打了“互联网”和“教育”两个标签集合的交集能告诉你它们的相关程度。场景三对比两份名单的差异。旧名单和新名单分别是两个集合新来的成员是新名单 - 旧名单离开的成员是旧名单 - 新名单。做数据对账的时候这套操作比循环加判断简洁太多。我在实际的数据清洗脚本里就常用集合做“白名单过滤”把允许通过的ID放进一个集合然后遍历数据用if id in allowed_set判断。这里值得说一句集合的成员判断速度非常快比列表的in要快很多——列表是逐个扫描集合是直接算哈希定位。数据量在几千以上时差距就很明显了这属于底层数据结构带来的性能红利。5. 三剑客的选型配合一篇实例看懂什么时候用哪个5.1 选型决策表讲了三种容器很多人到最后就会问我到底该用哪个我给你一个可以直接套用的选型表需求场景推荐容器原因按顺序保存、按位置访问的数据列表有序、可变、可切片定长、不需要修改的记录元组不可变、可哈希、语义清晰按名称/ID/键找对应值字典按键查找快映射关系明确去重、判断成员、集合关系运算集合天然去重哈希查找快保存一句话/一串字符字符串本身就是序列文本处理方法多这不只是一个“类型选择”问题更是一种数据建模思维。拿到需求先问三个问题数据有没有顺序需不需要按键找值要不要去重或求关系回答完容器类型自然就出来了。5.2 综合案例统计一篇文章的词频为了让你看到三者如何协同工作我做一个小案例统计一段英文文本里各单词出现的次数按频率由高到低输出前5名。这个案例是很多教程里的经典题但我会明确标出每一步用到了哪种容器、解决了什么问题。text apple banana apple cherry banana apple # 1. 分词拿到一个列表序列的典型应用 words text.split() print(words) # [apple, banana, apple, cherry, banana, apple] # 2. 去重拿到词汇表集合的典型应用 unique_words set(words) print(unique_words) # {apple, banana, cherry} # 3. 计数用字典建立词到次数的映射字典的典型应用 count {} for word in words: count[word] count.get(word, 0) 1 print(count) # {apple: 3, banana: 2, cherry: 1} # 4. 排序把字典的键值对转成列表再按值排序 ranked sorted(count.items(), keylambda item: item[1], reverseTrue) print(ranked[:5]) # [(apple, 3), (banana, 2), (cherry, 1)]这一步一步下来你会发现每一步换一种容器都是水到渠成分词产生列表去重需要集合计数使用字典排序又把字典变成列表去处理。没有哪一步是多余的也没有哪一步是为了炫技。这就是我在文章开头说的“容器思维”——你操作的始终是“一整批数据”不同的操作需求对应不同的数据结构。如果数据量再大一点或者单词本身需要清洗去掉标点、转为小写就在第1步前加一个列表推导式完成预处理。这些都是同样的思路。6. 常见问题与排查技巧实录最后这部分我把自己在入门阶段和带新人过程中反复遇到的报错和困惑整理成了一份速查表。每一项都是真实验证过的场景你可以直接当避坑指南用。现象/报错原因解决方案TypeError: unhashable type: list试图把列表当作字典键或集合元素把列表转成元组再使用字典赋值/查询时KeyError键不存在用方括号访问了改用get()方法或先用in判断{ }创建的变量类型是dict空花括号被解释为空字典空集合用set()创建集合去重后顺序发生变化集合用哈希存储不维护顺序用dict.fromkeys(列表)保留顺序切片结果和预期不一致没有注意结束位置取不到、步长方向检查[start:end:step]三个参数尤其是end字典遍历顺序和插入顺序不同误以为字典无序Python 3.7字典已按插入顺序保存有序是默认行为list.remove(x)删不掉元素直接按值删除只删第一个匹配项不确定是否存在会报错先if x in lst判断或用列表推导式过滤count[word] count[word] 1报KeyError第一次遇到新单词时字典里没有键用count.get(word, 0) 1先取默认值再补一个我在实际项目中经常提醒组员的细节列表的引用陷阱。a [1, 2, 3] b a b.append(4) print(a) # [1, 2, 3, 4]这里b a不是复制列表而是让两个变量指向同一个列表对象。修改ba也会变。如果你想复制一份互不影响要用a.copy()或a[:]。新手在这个问题上栽跟头的概率极高尤其是当列表作为函数参数传进传出的场景。a [1, 2, 3] b a.copy() # 真正的新列表 b.append(4) print(a) # [1, 2, 3] print(b) # [1, 2, 3, 4]另外一个和它相关的深层坑是“浅拷贝”。如果你的列表里嵌套了可变对象比如a [[1], [2]]那么a.copy()只复制了外层内层子列表还是共享的。这种情况如果想深度复制就用import copy; copy.deepcopy(a)。入门阶段先记住“复制列表用copy方法嵌套多就用deepcopy”后面学到面向对象和复杂数据结构时会更理解背后的对象模型。结尾最后聊点体会。我带过不少新人观察到一个规律语法学得最快的人往往也是容器用得最熟的。因为容器就是组织数据的单元数据组织得好算法和逻辑才有施展空间。我自己的习惯是这样拿到数据先想清楚它是“有顺序的序列”还是“需要按键找值的映射”或者“只需判断在不在的集合”想清楚再动手写代码几乎不会走弯路。还有个小技巧想分享给你练这部分内容不要只做书本上的填空题。找一份真实的数据比如你手机的通讯录导出、一份CSV日志、一篇英文文章尝试用今天讲的列表、字典、集合去完成“去重、分组、统计、对比”这几个动作。你练得越多越能体会到为什么Python把这些数据结构做成内置类型——因为它们真的是日常开发的地基不是绕不开的理论而是用了就离不开的工具。下一期可以顺着这条路把字符串处理里的常用方法继续补全也能讲讲列表和字典的嵌套结构怎么组织复杂数据。先把今天这些操作敲熟后面很多内容都会变得很顺。
企业数字化 ERP 产品动态
相关推荐
SAP销售寄售业务全解:从补货到结算的配置与操作避坑指南 简介:针对SAP销售寄售业务配置和操作的PDF资料,面向SD顾问及实施运维人员,覆盖寄售补货、销售结算、寄售退回及寄售退货的完整业务链路。文档详细拆解KB、KE、KR、KAN四种单据类型对应的行项目类别、计划行类别、移动类型及交货单配置&#x… · 2026/9/23 14:24:00
S4 HANA 1909常规配置指南:从OBYC到BP的关键设置与避坑实践 简介:面向SAP顾问、实施及运维人员的SAP常规配置详解PDF,基于S4 HANA 1909版本演示讲解。内容聚焦国家定义、计量单位、货币与维护日历四大基础设置,每个部分均给出IMG配置路径、功能说明与参数含义。例如国家设置涉及邮政编码、银行信息与日… · 2026/9/23 15:11:54
搞定www.net性能优化,面试不再被问倒 搞定www.net性能优化,面试不再被问倒 复制来的代码跑不通,是不是常让你抓狂?别急,先别急着删库跑路。在大厂面试中,关于 www.net 这类网络域名的处理,往往藏着性能优化的深坑。很多候选人只懂调用,不懂底层原理,一问就露馅。… · 2026/9/23 15:11:54
医院网络升级改造全攻略:从现状评估到架构优化实施 简介:面向医院信息科、网络运维及智慧医疗建设人员,这份资源以“医院信息化网络升级改造”为主题,系统梳理了医院网络从早期HIS系统到多子系统阶段的演进痛点,包括结构不合理、二层交换技术缺陷、VLAN无法划分导致的广播风暴、IP管… · 2026/9/23 15:11:47
Apache Druid 数据留存规则实战:基于 Retention Rules 配置数据的保留与丢弃 Apache Druid 数据留存规则实战:基于 Retention Rules 配置数据的保留与丢弃 【免费下载链接】druid Apache Druid: a high performance real-time analytics database. 项目地址: https://gitcode.com/gh_mirrors/druid6/druid
本教程演示如何通过 Apache D… · 2026/9/23 15:11:41
使用 cy.autolock() 全局锁定 Cytoscape.js 节点:API 用法、底层实现与实战指南 使用 cy.autolock() 全局锁定 Cytoscape.js 节点:API 用法、底层实现与实战指南 【免费下载链接】cytoscape.js Graph theory (network) library for visualisation and analysis 项目地址: https://gitcode.com/gh_mirrors/cy/cytoscape.js
本文围绕 Cytosc… · 2026/9/23 15:11:34
Codex汉化完整指南:从安装配置到中文界面 第一次打开Codex的时候,我盯着终端里满屏的英文提示愣了好几秒。说实话,作为一个常年跟命令行打交道的人,英文界面本身不算什么大问题,真正让我烦躁的是提示信息里那些缩写和术语,经常要停下来想一下这个参数到底是干什… · 2026/9/23 15:11:33
3招搞定手机怎么下载微信面试难题实战项目解析 3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29