ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

practical-python 课程 1.5:深入掌握 Python 列表——创建、索引、排序与源码实战

practical-python 课程 1.5:深入掌握 Python 列表——创建、索引、排序与源码实战 教程文档【免费下载链接】practical-pythonPractical Python Programming (course by dabeaz)项目地址https://gitcode.com/gh_mirrors/pr/practical-python点击查看免费下载本篇技术指南围绕 practical-python 课程第 1.5 节Notes/01_Introduction/05_Lists.md展开系统讲解 Python 列表——这门课程中用于保存有序值集合的首要内置类型。作为课程的数据基础章节列表将贯穿后续所有示例从第 2 节的数据处理、第 4 节的对象建模到第 6 节的生成器流水线。读完本篇你将掌握列表的创建、索引、切片、增删、排序等全部核心操作理解*与在列表上的真实语义并能将列表与split()、join()、for循环等组合起来处理真实数据如股票 CSV 记录同时通过本仓库的pcost.py、report.py、portfolio.py等源码印证这些操作的实战用法。列表Python 有序集合的基础类型列表list是 Python 用于保存有序的值集合的主要类型。与后面章节会遇到的元组tuple不同列表是可变的mutable——创建之后可以随时增删改元素。它是本课程后续所有数据处理示例的基石CSV 行解析、投资组合记录、股票报价流本质上都是列表 迭代的运用。创建列表用方括号[ ]定义列表字面量元素之间以逗号分隔names [ Elwood, Jake, Curtis ] nums [ 39, 38, 42, 65, 111]也可以从一个空列表开始逐步append()元素这在后面的练习与Portfolio类中非常常见mysyms [] mysyms.append(GOOG)通过split()从字符串创建列表列表常由其他操作间接产生。例如字符串的split()方法可以把一段文本按分隔符切成列表——这是解析 CSV 行数据的起点 line GOOG,100,490.10 row line.split(,) row [GOOG, 100, 490.10] 注意split()得到的元素全是字符串数值字段需要后续转换见下文源码实战。这是本课程股票数据处理的经典模式先切分、再转换、再收集。列表核心操作列表可以容纳任意类型的元素数字、字符串、甚至其他列表并提供一套完整的操作手段。追加与插入append()、insert()names.append(Murphy) # Adds at end names.insert(2, Aretha) # Inserts in middleappend(x)把元素添加到列表末尾insert(i, x)把元素插入到索引i指定的位置其后的元素自动后移。连接用运算符拼接两个列表产生一个新列表原列表不变s [1, 2, 3] t [a, b] s t # [1, 2, 3, a, b]索引从 0 开始的整数下标列表用整数索引访问元素下标从 0 开始names [ Elwood, Jake, Curtis ] names[0] # Elwood names[1] # Jake names[2] # Curtis负索引从末尾开始计数-1是最后一个元素names[-1] # Curtis修改元素列表是可变的任意位置的元素都可以重新赋值names[1] Joliet Jake names # [ Elwood, Joliet Jake, Curtis ]长度len()names [Elwood,Jake,Curtis] len(names) # 3成员测试in/not inElwood in names # True Britney not in names # True复制s * n列表乘以整数会把自身内容重复 n 份返回新列表s [1, 2, 3] s * 3 # [1, 2, 3, 1, 2, 3, 1, 2, 3]迭代与搜索for循环遍历列表用for逐个取出列表元素这与其他语言中的foreach语句类似for name in names: # use name # e.g. print(name) ...for循环的工作方式是遍历序列中的数据列表正是最典型的序列。后续章节Notes/06_Generators/01_Iteration_protocol.md会进一步解释迭代协议届时你会看到for实际上是调用迭代器协议完成的。用index()查找位置names [Elwood,Jake,Curtis] names.index(Curtis) # 2两点需要特别记住若元素出现多次index()只返回第一次出现的索引若元素不存在会抛出ValueError异常。因此调用index()之前通常先用in做成员测试或用异常处理兜底本课程 Notes/03_Program_organization/03_Error_checking.md 会系统讲解错误处理。删除元素可以按值删除也可以按下标删除# Using the value names.remove(Curtis) # Using the index del names[1]删除元素不会留下空洞——后面的元素会自动前移填补空位。如果列表中存在多个相同元素remove()只删除第一次出现的那个。del还可以配合切片一次性删除多个元素例如del names[1:3]。排序原地排序sort()列表自带sort()方法就地in-place重排元素不产生新列表s [10, 1, 7, 3] s.sort() # [1, 3, 7, 10] # Reverse order s [10, 1, 7, 3] s.sort(reverseTrue) # [10, 7, 3, 1] # It works with any ordered data s [foo, bar, spam] s.sort() # [bar, foo, spam]只要元素之间存在大小比较关系数字按数值、字符串按字典序sort()都能工作。返回新列表sorted()如果不想改动原列表用内置函数sorted()生成一个新的已排序列表t sorted(s) # s unchanged, t holds sorted values记忆要点sort()是列表的方法就地修改sorted()是内置函数返回新列表。列表与数学注意列表并不是为数学运算设计的。 nums [1, 2, 3, 4, 5] nums * 2 [1, 2, 3, 4, 5, 1, 2, 3, 4, 5] nums [10, 11, 12, 13, 14] [1, 2, 3, 4, 5, 10, 11, 12, 13, 14]这里的*是重复复制是拼接都不是向量/矩阵意义上的标量乘法或逐元素加法。列表不能像 MATLAB、Octave、R 那样直接当作向量或矩阵使用。如果确实需要数值计算应使用专门的第三方包如 numpy而不是用原生列表模拟。源码实战列表在课程项目中的应用列表不是孤立的概念本仓库的练习代码几乎处处依赖它。以下实例都来自仓库中的可运行源码可以打开对照阅读。1. 用split()解析 CSV 行pcost.pySolutions/1_27/pcost.py 是课程早期的投资组合成本程序它逐行读取Work/Data/portfolio.csv用split(,)把每行切成列表再按下标取字段并转换类型row line.split(,) nshares int(row[1]) price float(row[2]) total_cost nshares * price这正是 1.5 节GOOG,100,490.10.split(,)示例的直接应用切分 → 索引 → 类型转换 → 累加。切分得到的row是字符串列表int()/float()完成数值化。2. 用列表收集记录report.pySolutions/2_11/report.py 展示了列表作为记录收集器的典型用法遍历 CSV 行把每行构造成一个字典append进portfolio列表随后再遍历该列表生成(name, shares, price, change)元组列表report最后用for循环输出for row in rows: stock { name : row[0], shares : int(row[1]), price : float(row[2]) } portfolio.append(stock) ... for row in report: print(%10s %10d %10.2f %10.2f % row)可以看到空列表 → 循环 append → 遍历使用三步曲贯穿整个课程。课程后半部分Solutions/7_11/report.py改为对象与格式化器后make_report()依旧返回一个列表rows [] for s in portfolio: current_price prices[s.name] change current_price - s.price summary (s.name, s.shares, current_price, change) rows.append(summary) return rows3. 用列表承载对象portfolio.pySolutions/7_11/portfolio.py 中的Portfolio类在内部用一个列表_holdings存放Stock对象并通过__iter__、__len__、__getitem__把列表的迭代、长度、索引能力借用给自定义类self._holdings [] ... def append(self, holding): self._holdings.append(holding) def __iter__(self): return self._holdings.__iter__() def __len__(self): return len(self._holdings) def __getitem__(self, index): return self._holdings[index]而tabulate_shares()方法则演示了遍历列表 计数的组合——用collections.Counter统计每只股票的总持股数。Stock对象本身Solutions/7_11/stock.py也借助 f-string 输出repr印证了 1.5 节列表可容纳任意对象的说法。4. 用列表推导过滤与转换ticker.pySolutions/7_11/ticker.py 中select_columns用列表推导[row[index] for index in indices]按索引挑选列convert_types用zip(types, row)逐列转换类型过滤条件row[name] in portfolio则直接运用了 1.5 节的成员测试def select_columns(rows, indices): for row in rows: yield [row[index] for index in indices]列表推导是本节迭代 构建新列表的自然延伸课程第 2 节Notes/02_Working_with_data/06_List_comprehension.md会系统讲解。课程练习亲手实验列表Exercises 1.19–1.25以下练习来自 Notes/01_Introduction/05_Lists.md请在 Python 交互式提示符下逐条输入观察输出。上一节 1.4 Strings 中你接触过包含股票代码的字符串本节把它变成列表继续实验。提示交互提示符下是解释器提示符不要输入本身。先准备数据——把一个逗号分隔的股票代码字符串切成列表 symbols HPQ,AAPL,IBM,MSFT,YHOO,DOA,GOOG symlist symbols.split(,)Exercise 1.19提取与重新赋值列表元素尝试几次下标查找正索引、负索引 symlist[0] HPQ symlist[1] AAPL symlist[-1] GOOG symlist[-2] DOA 重新赋值一个元素 symlist[2] AIG symlist [HPQ, AAPL, AIG, MSFT, YHOO, DOA, GOOG] 做几次切片 symlist[0:3] [HPQ, AAPL, AIG] symlist[-2:] [DOA, GOOG] 切片[start:stop]包含start、不包含stop与字符串切片规则一致。创建一个空列表并追加一个元素 mysyms [] mysyms.append(GOOG) mysyms [GOOG]把一个列表片段整体替换成另一个列表——左侧列表会按需缩放以容纳右侧内容 symlist[-2:] mysyms symlist [HPQ, AAPL, AIG, MSFT, YHOO, GOOG] 在上例中symlist末尾两个元素被mysyms的单个元素替换列表自动缩短。Exercise 1.20用for循环遍历列表for循环对序列如列表中的数据逐个迭代。输入下面的循环并观察输出 for s in symlist: print(s , s) # Look at the outputExercise 1.21成员测试用in/not in检查AIG、AA、CAT是否在symlist中 # Is AIG IN the symlist? True # Is AA IN the symlist? False # Is CAT NOT IN the symlist? True Exercise 1.22追加、插入与删除元素用append()把RHT加到symlist末尾 # append RHT symlist [HPQ, AAPL, AIG, MSFT, YHOO, GOOG, RHT] 用insert()把AA插为第二个元素 # Insert AA as the second item in the list symlist [HPQ, AA, AAPL, AIG, MSFT, YHOO, GOOG, RHT] 用remove()删除MSFT # Remove MSFT symlist [HPQ, AA, AAPL, AIG, YHOO, GOOG, RHT] 在末尾追加一个重复的YHOO——列表允许出现重复值 # Append YHOO symlist [HPQ, AA, AAPL, AIG, YHOO, GOOG, RHT, YHOO] 用index()找到YHOO第一次出现的位置并验证该位置确实是它 # Find the first index of YHOO 4 symlist[4] YHOO 用count()统计YHOO出现的次数 symlist.count(YHOO) 2 删除第一次出现的YHOO # Remove first occurrence YHOO symlist [HPQ, AA, AAPL, AIG, GOOG, RHT, YHOO] 需要说明列表没有直接查找/删除全部出现项的方法。课程第 2 节会介绍一种优雅的解决方案——列表推导见 Notes/02_Working_with_data/06_List_comprehension.md例如[x for x in symlist if x ! YHOO]即可一次性过滤掉全部匹配项。Exercise 1.23排序用sort()就地排序 symlist.sort() symlist [AA, AAPL, AIG, GOOG, HPQ, RHT, YHOO] 用sort(reverseTrue)降序排序 symlist.sort(reverseTrue) symlist [YHOO, RHT, HPQ, GOOG, AIG, AAPL, AA] 注意sort()是就地修改——元素在原有列表内部被打乱重排不创建新列表。若要保留原列表改用sorted(symlist)。Exercise 1.24用join()把列表拼回字符串用字符串的join()方法可以把字符串列表连接成一个字符串注意join是字符串的方法分隔符写在左侧首次见到会觉得看起来有点怪 a ,.join(symlist) a YHOO,RHT,HPQ,GOOG,AIG,AAPL,AA b :.join(symlist) b YHOO:RHT:HPQ:GOOG:AIG:AAPL:AA c .join(symlist) c YHOORHTHPQGOOGAIGAAPLAA ,.join(...)恰好是split(,)的逆操作——CSV 文本与列表之间的往返转换正是本课程数据文件的处理核心。Exercise 1.25列表里可以装任何东西列表可以容纳任意对象包括其他列表嵌套列表 nums [101, 102, 103] items [spam, symlist, nums] items [spam, [YHOO, RHT, HPQ, GOOG, AIG, AAPL, AA], [101, 102, 103]]请仔细看上面的输出items是一个含三个元素的列表——第一个元素是字符串另外两个元素本身就是列表。用多重索引访问嵌套列表中的元素 items[0] spam items[0][0] s items[1] [YHOO, RHT, HPQ, GOOG, AIG, AAPL, AA] items[1][1] RHT items[1][1][2] T items[2] [101, 102, 103] items[2][1] 102 每一步索引都进入更深一层items[1][1]先取items的第二个元素列表再取其中第二个元素items[1][1][2]甚至继续取到字符串RHT的第三个字符T。经验法则虽然技术上可以构造非常复杂的嵌套列表结构但通常应保持简单。一般来说一个列表中的元素应是同一种类型的值——要么全是数字要么全是字符串。把不同类型的数据混在一个列表里往往是自找麻烦应尽量避免。小结与下一步本节建立起了列表操作的全套工具箱创建字面量、split()、增删append/insert/remove/del、索引与切片、成员测试、排序sort/sorted并厘清了列表上*、的复制/拼接语义。这些能力在仓库的练习代码中反复出现——无论是pcost.py的行切分、report.py的记录收集还是portfolio.py的对象容器都以列表为地基。下一节 1.6 Files 将把列表与文件读取结合起来真正开始处理磁盘上的数据文件更深入的数据结构与列表推导则在第 2 节Notes/02_Working_with_data/00_Overview.md展开。回到课程目录请见 Contents上一节回顾 1.4 Strings。赞分享教程文档【免费下载链接】practical-pythonPractical Python Programming (course by dabeaz)项目地址https://gitcode.com/gh_mirrors/pr/practical-python点击查看免费下载相关推荐Practical Python教程深入理解Python序列操作Practical Python教程深入理解Python序列操作 序列数据类型概述 Python中有三种主要的序列数据类型它们都是有序的、可通过整数索引访问教程文档Practical Python 课程实战用 setup.py 与 MANIFEST.in 打包分发你的 Python 代码Practical Python 课程实战用 setup.py 与 MANIFEST.in 打包分发你的 Python 代码 本篇技术指南围绕 Practic教程文档Practical Python 项目解析深入理解列表推导式Practical Python 项目解析深入理解列表推导式 列表推导式概述 列表推导式List Comprehensions是 Python 中一种简洁教程文档上一篇幻兽帕鲁存档编辑完全指南3个实用技巧让游戏体验翻倍下一篇VidBee 视频下载完整指南手动、扩展、RSS 三种取片方式一次讲清创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表