尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

05 列表:批量数据的容器(增删改查 · 可变与不可变 · 排序统计)

05 列表:批量数据的容器(增删改查 · 可变与不可变 · 排序统计) 上一篇04 字符串详解办公场景的第一刚需拼接 · 切片 · f-string · 清洗三件套上篇练习参考答案练习 1脱敏变式把手机号脱敏改成显示前 3 位和后 2 位、中间打 6 个星如 138******78只用切片和拼接实现phone12345678910print(phone[:3]**6phone[-2:])# 123******10注意* * 6的写法——字符串乘法比手打六个星专业。练习 2预测再验证先写出 len(“Python”)、“Python”[0:2]、“PYTHON”.lower() “python” 三项的结果再进交互模式验证错的写在评论区len(Python)→6Python[0:2]→Py含头不含尾PYTHON.lower() python→True先变身再比较大小写无关比对的套路练习 3名单整理参考答案有名单 张三 李四 王五、赵六 用 replace 统一分隔符后 split join输出 张三、李四、王五、赵六并用 len() 数出一共几人raw 张三 李四 王五、赵六 namesraw.replace( ,).replace(,、).replace(,、).split(、)print(、.join(names))# 张三、李四、王五、赵六print(f共{len(names)}人)# 共 4 人亮点在第一个 replacereplace( , )一把去掉所有空格——包括名字中间的——这正是 04 篇坑 2strip 管不了中间的正解。然后统一分隔符、split、join四步一条龙。数人数用len()再也不用肉眼数逗号。练习 4千分位洗数字把 “1,258,045” 变回数字 1258045.0提示先 replace 去千分位逗号再 float 变身——Excel 导出的数字常带千分位逗号这就是洗它的标准姿势。print(float(1,258,045.replace(,,)))# 1258045.0一、场景引入从一个变量到一沓数据到今天为止我们一个变量只能装一个值name1 张三、name2 李四、name3 王五……名单 500 人怎么办写 500 行**列表list **就是为此而生一个变量装下一整沓数据。它可以装 500 个名字、365 天的销售额、一个文件夹里所有文件名——而且这沓数据能动态增删早上 3 项待办老板随时加一项、做完随时划掉一项。列表是你和批量数据打交道的起点后面每一篇都会用到它06 篇的字典会嵌进列表、08 篇的循环会遍历列表、模块二的 pandas 本质上是加强版列表。本篇结尾你会拥有上面那个待办清单指挥中心一条完整工作日的增删改查时间线。二、本篇目标会创建列表用len()、索引、切片查数据放心规则和字符串完全一样掌握增删改查四板斧append / insert / remove / pop / 按下标赋值 / in理解列表和字符串的根本区别可变与不可变这一条能解开你 04 篇的遗留疑惑会用sum / max / min / sorted / sort做小统计。三、知识点讲解3.1 创建与查看规则和字符串一模一样用方括号[]创建元素之间用逗号分隔todos[写周报,回复客户邮件,整理下载文件夹]# 装字符串scores[85,92,78,95]# 装数字mixed[张三,18,175.5,True]# 也能混装但建议同类empty[]# 空列表先建好袋子以后再装查看三件套——编号规则、切片语法、含头不含尾全部沿用 04 篇直接看对应关系todos[写周报,回复客户邮件,整理下载文件夹]# 编号: 0 1 2print(len(todos))# 3元素个数print(todos[0])# 写周报从 0 开始数print(todos[-1])# 整理下载文件夹-1 永远是最后一个print(todos[0:2])# [写周报, 回复客户邮件]含头不含尾切出来还是列表print(写周报intodos)# Truein 判断也通用唯一的新面孔字符串切出来还是一段文字列表切出来还是一个列表todos[0:2]的结果用方括号包着。3.2 增删改查四板斧增——两种加法todos[写周报,回复客户邮件]print(todos)todos.append(准备周五汇报)# append加到队尾最常用todos.insert(0,处理线上客诉)# insert插到指定编号处后面的自动往后挪print(todos)# 现在 todos[0] 是 处理线上客诉原第一项被挤到 todos[1]删——三种删法按场景选todos.remove(回复客户邮件)# 按内容删知道删什么用它donetodos.pop(0)# 按编号删取走并带回这个值取走第 0 项todos.pop()# 括号留空 取走最后一项deltodos[0]# del 语句按编号删且不要返回值少用知道即可改——就是按下标赋值todos[0]写周报含数据图表# 第 0 项直接覆盖查——in和索引print(写周报intodos)# 在不在print(todos[-1])# 取最后一个四板斧一句话记加用 append、删用 remove知道内容或 pop知道位置、改用中括号赋值、查用 in。3.3 可变与不可变列表和字符串的根本区别本篇灵魂回忆 04 篇报错区那句提醒“字符串方法必须x x.strip()接住结果不然白洗”。当时没解释为什么——现在可以了字符串是不可变的immutable任何操作都改不了它自己只能返回一个新的字符串所以必须用变量接住namechenname.upper()# 白干生成了 CHEN 但没人接住name 还是 chennamename.upper()# 正确新字符串接回 name列表是可变的mutable方法直接作用在原列表身上原地生效不需要接todos[写周报]todos.append(回邮件)# 直接改了 todos 本身不需要 todos todos.append(...)print(todos)# [写周报, 回邮件]所以记住这条铁律字符串.strip()要接、列表.append()不接。写了todos todos.append(...)反而会出大事——append 默默返回 None你的 todos 会变成空空如也的 None这个坑放在第六节。这不是需要死记的语法是两种容器的本性一个是刻在石头上的字改不了只能重刻一块一个是白板随时擦写。顺带解释一个现象print(todos)直接打印列表会看到[写周报, 回邮件]带着引号和方括号——那是它的素颜调试视图。给人看的输出用 04 篇的 join 化个妆print( | .join(todos))# 写周报 | 回邮件3.4 排序与统计小工具箱数字列表天生适合算账五个内置函数一网打尽minutes[30,45,20,60]print(sum(minutes))# 155 总和print(max(minutes))# 60 最大print(min(minutes))# 20 最小print(f{sum(minutes)/len(minutes):.1f})# 38.8 平均总和除以个数:,.1f 控制一位小数排序两兄弟一字之差、行为完全不同又是可变性的现场教学scores[78,95,85,60]print(sorted(scores))# [60, 78, 85, 95]返回一个新列表scores 原序不动scores.sort()# 原地重排scores 自己变成排好的样子返回 Noneprint(scores)# [60, 78, 85, 95]结论想保住原顺序做展示用sorted()确定要重排且不再需要原序才用.sort()。新手期一律推荐sorted()——它不改原件更安全。sorted()还能倒着排sorted(scores, reverseTrue)→[95, 85, 78, 60]从高到低做排行榜就靠它。一句诚实的说明sorted()排英文按字母序、排中文按编码序不是拼音序——名单要按姓氏笔画或拼音排属于模块四 pandas 的进阶活现在知道边界即可。四、完整实战待办清单指挥中心场景把一个工作日的信息流串起来——早上看清单、老板加需求、客诉插队、升级需求、完成划掉、下班统计。新建待办清单指挥中心.py# 待办清单指挥中心 # 一、初始清单todos[写周报,回复客户邮件,整理下载文件夹]print(*44)print( 待办清单指挥中心)print(*44)print(f[早上] 共{len(todos)}项)print( | .join(todos))# 二、增append 尾部追加todos.append(准备周五汇报)print(f\n[9:00 老板加需求] append 追加后共{len(todos)}项)print( | .join(todos))# 三、增insert 插到最前todos.insert(0,处理线上客诉)print(f\n[9:05 客诉插队] insert(0, ...) 后第一项变成{todos[0]})print( | .join(todos))# 四、改按下标改todos[1]写周报含数据图表print(f\n[10:00 需求升级] 第 2 项改为{todos[1]})# 五、删remove 按内容删todos.remove(回复客户邮件)print(f\n[11:00 完成邮件] remove 划掉后剩{len(todos)}项)print( | .join(todos))# 六、查in 判断注意列表的 in 是整项精确匹配print(f\n[14:00 盘点] 写周报还在待办里吗{写周报intodos})print(f[14:00 盘点] 写周报含数据图表还在吗{写周报含数据图表intodos})# 七、删pop 按编号取走donetodos.pop(0)print(f[17:00 pop 取走第 1 项去执行]{done})print(f剩余{len(todos)}项)print( | .join(todos))# 八、排序预览sorted 不动原顺序print(f\n[下班前] 按编码排序预览{、.join(sorted(todos))})# 九、数字统计每项预计用时minutes[30,45,20,60]print(-*44)print(今日预计用时统计)print(f 总计{sum(minutes)}分钟最长{max(minutes)}分钟最短{min(minutes)}分钟)print(f 平均每项{sum(minutes)/len(minutes):.1f}分钟)print(*44)留意代码里三处细节展示清单全用 | .join(todos)给人看的排版pop(0)取走的值用done接住pop 与 remove 的关键差异它有返回值平均数用:.1f控制小数位04 篇 f-string 格式化的复习。这段代码没有一行需要你手工数数——len()数项数、sum()算总时长这就是批量思维和手工思维的差距。五、运行效果 待办清单指挥中心 [早上] 共 3 项 写周报 | 回复客户邮件 | 整理下载文件夹 [9:00 老板加需求] append 追加后共 4 项 写周报 | 回复客户邮件 | 整理下载文件夹 | 准备周五汇报 [9:05 客诉插队] insert(0, ...) 后第一项变成处理线上客诉 处理线上客诉 | 写周报 | 回复客户邮件 | 整理下载文件夹 | 准备周五汇报 [10:00 需求升级] 第 2 项改为写周报含数据图表 [11:00 完成邮件] remove 划掉后剩 4 项 处理线上客诉 | 写周报含数据图表 | 整理下载文件夹 | 准备周五汇报 [14:00 盘点] 写周报还在待办里吗False [14:00 盘点] 写周报含数据图表还在吗True [17:00 pop 取走第 1 项去执行]处理线上客诉 剩余 3 项 写周报含数据图表 | 整理下载文件夹 | 准备周五汇报 [下班前] 按编码排序预览写周报含数据图表、准备周五汇报、整理下载文件夹 -------------------------------------------- 今日预计用时统计 总计 155 分钟最长 60 分钟最短 20 分钟 平均每项 38.8 分钟 对照输出确认三个理解点insert(0, ...)之后原来的写周报从第 0 项变成了第 1 项后面自动往后挪pop(0)取走后剩余项目自动补位14:00 的盘点是个彩蛋——查写周报得到 False、查全名写周报含数据图表才是 True。因为 10:00 那次改名之后列表里就没有叫写周报的那一项了。列表的in是整项精确匹配和字符串的in子串包含写 in 写周报是 True不是一回事。列表自己管理编号和成员你只管下令。六、常见报错与排查报错 1IndexError: list index out of range越界老朋友了todos [写周报, 回邮件] print(todos[2]) IndexError: list index out of range原因只有 2 个元素、编号 0~1取[2]越界。和 04 篇字符串越界同款。解决len()先数一遍末元素直接用todos[-1]永不越界。报错 2ValueError: list.remove(x): x not in list删除不存在的内容todos.remove(回复邮件) ValueError: list.remove(x): x not in list原因清单里压根没有这一项注意大小写和空格——回复邮件和回复客户邮件不是一回事。解决先print(todos)或x in todos确认存在再删更稳的写法第 11 篇异常篇会教。报错 3TypeError: list indices must be integers or slices, not str用文字当下标names [张三, 李四] print(names[张三]) TypeError: list indices must be integers or slices, not str原因列表只能用编号取值“张三是内容不是编号。你真正想要的功能是用名字直接取值”——那是字典的绝活下一篇正式开讲这个报错就是通往 06 篇的传送门。报错 4TypeError: not supported between instances of int and str混装列表排序sorted([张三, 18]) TypeError: not supported between instances of int and str原因排序要两两比较大小Python 不知道 “张三” 和 18 谁大。解决保持一个列表装同类数据这也是 3.1 节建议同类的原因混装列表要么先挑出数字再排要么不排。坑 1不报错但结果错todos todos.append(...)把清单弄丢了3.3 节说过列表方法是原地生效、返回 None。todos todos.append(x)等于把 None 塞回 todos——之后再用 todos 就报AttributeError: NoneType object has no attribute append。解决append 这类列表方法单独占一行左边永远不要写等号。坑 2不报错但结果错append 一整个列表越加越多层t[a,b]t.append([c,d])print(t)# [a, b, [c, d]] 不是 [a, b, c, d]print(len(t))# 3不是 4append 把[c, d]当成一个元素塞进去t 变成两层嵌套。想一次加多个元素逐个 append或用 extendt.extend([c, d])才会让 len 变 4。七、练习作业5 分钟手动模拟本篇核心题请拿纸笔做依次执行下面的代码每一步后写下print(todos)的结果全部写完再上机逐行验证todos[晨会,审合同]todos.append(订机票)todos.insert(1,发日报)todos.remove(晨会)donetodos.pop()todos[0]审合同修订版最后 todos 是什么done 是什么答对 5 步以上的同学列表这一关算过了预测再验证len([1, 2, 3])、[1, 2, 3][-1]、sum([1, 2, 3])、sorted([3, 1, 2], reverseTrue)各是什么写下来进交互模式验证错的贴评论区成绩小报表scores [78, 95, 85, 60, 92]用本篇函数不用循环打印人数、总分、平均分一位小数、最高分、最低分并按从高到低排好打印选做06 篇疫苗执行info [张三, 18]、info[1] info[1] 1后print(info)再试试用info[姓名]取值看报什么错——感受编号取值的不便你就明白下一篇字典为什么存在。下一篇预告《06 字典键值对组织数据》——告别第 0 项是什么来着的编号记忆用info[姓名]直接按名字取值。顺便讲清 JSON爬虫和接口吐出来的数据全是它的方言。
返回列表