在本节课中,我们将学习 Python 中的列表(List)这种常用数据结构。通过实例和练习,掌握列表的定义、基本操作及其应用。
索引是指通过位置访问序列中的某个元素。Python 中的索引从 0 开始。
例如:
cities = ["北京", "上海", "广州", "成都"]
print(cities[0]) # 输出“北京”
切片是指通过索引范围提取一段序列的子集。语法为:
序列[起始索引:结束索引:步长]
说明:
例如:
cities[1:3] # 输出 ["上海", "广州"]
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
|---|---|---|---|---|---|---|---|---|---|---|
| 正索引 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
| 负索引 | -10 | -9 | -8 | -7 | -6 | -5 | -4 | -3 | -2 | -1 |
| 值 | A | B | C | D | E | F | G | H | I | J |
补充说明:
如果列表内容是 ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'],则上表展示了如何通过正索引和负索引访问这些字母。
例如:list[0] → 'A',list[-1] → 'J'
列表是 Python 中用来存储一组有序的数据的数据结构,可以包含数字、字符串、甚至是其他列表。列表用中括号 [] 表示,元素之间用逗号 , 分隔。
一个列表的例子:
["历史", "哲学", "文学"]
list('四川外国语大学')
['四', '川', '外', '国', '语', '大', '学']
参数可以是字符串、元组、字典或者集合。但不能是整数、浮点数或者布尔值:
#list(100.8)
这里出现TypeError的异常,表示float对象是不能被迭代的。也就是说,在list函数只能将可迭代对象转换为列表。
使用方括号[]创建列表时,需要在列表中列出所有元素:
my_list = ['四川外国语大学']
my_list
['四川外国语大学']
my_list2 = ['四','川','外','国','语','大','学'] #list("四川外国语大学")
my_list2
['四', '川', '外', '国', '语', '大', '学']
可以使用list函数和方括号[ ]创建空列表:
list()
[]
[]
[]
列表也可以包含其他列表值。这些列表的列表中的值,可以通过多重下标来访问,像这样:
# 编号,姓名,研究经费,奖学金,住宿补贴,学校服务费,材料费,学术活动开支
projectList = [
['20231','周文哲',15000.00,4000.00,2300.00,980.00,300.00,1000.00], # 文化遗产保护项目
['20232','王思齐',12000.00,5000.00,2600.00,890.00,400.00,2000.00], # 社会调查专项
['20233','李慕白',10100.00,2000.00,2500.00,860.00,500.00,1500.00], # 口述史研究计划
['20234','陈清扬',10050.00,1000.00,2700.00,1080.00,300.00,2000.00],# 方言田野调查
['20235','林语墨',10200.00,2000.00,2400.00,1000.00,600.00,1000.00],# 非物质文化遗产整理
['20241','沈从文',13600.00,4000.00,2100.00,680.00,300.00,1000.00], # 民俗艺术研究
['20242','梁思语',13200.00,2500.00,2300.00,670.00,400.00,3000.00], # 性别研究课题
['20245','费孝通',13600.00,2600.00,2030.00,560.00,400.00,2000.00], # 乡村社会结构调研
['20246','钱钟书',12500.00,2800.00,2400.00,420.00,500.00,1500.00], # 比较文学研究
['20247','吴文藻',12000.00,3500.00,2030.00,880.00,300.00,1000.00], # 社区发展研究
['20248','郑天挺',14200.00,2500.00,2020.00,900.00,400.00,2000.00] # 历史档案数字化
]
projectList[8][1]
'钱钟书'
projectList[2][1]
'李慕白'
课堂活动
我们以一些文科相关的例子来演示列表的定义和使用。
# 创建一个包含不同文科课程的列表
courses = ["历史", "哲学", "文学", "语言学", "社会学"]
print("文科课程列表:", courses)
文科课程列表: ['历史', '哲学', '文学', '语言学', '社会学']
由于列表是可变的, 因此列表有些专用的方法: 元素增加、元素修改、元素删除和分片赋值。这些方法都是在列表原位置进行修改,也就是改变了列 表本身的值,而不是创建新的列表。
# 考古遗址名录管理
heritage_sites = ["殷墟", "兵马俑", "敦煌莫高窟"]
heritage_sites.append("良渚古城")
print("更新后名录:", heritage_sites)
# 输出:['殷墟', '兵马俑', '敦煌莫高窟', '良渚古城']
heritage_sites = ["殷墟", "兵马俑", "敦煌莫高窟"]
heritage_sites.append("良渚古城")
print("更新后名录:", heritage_sites)
更新后名录: ['殷墟', '兵马俑', '敦煌莫高窟', '良渚古城']
# 合并两个考古团队的研究数据
team_a = ["陶器分析", "碳14测年"]
team_b = ["甲骨文研究", "青铜器修复"]
team_a.extend(team_b)
print("整合后研究领域:", team_a)
# 输出:['陶器分析', '碳14测年', '甲骨文研究', '青铜器修复']
# 合并两个考古团队的研究数据
team_a = ["陶器分析", "碳14测年"]
team_b = ["甲骨文研究", "青铜器修复"]
team_a.extend(team_b)
print("整合后研究领域:", team_a)
# 输出:['陶器分析', '碳14测年', '甲骨文研究', '青铜器修复']
整合后研究领域: ['陶器分析', '碳14测年', '甲骨文研究', '青铜器修复']
| 方法 | 操作对象 | 修改方式 | 返回值 | 典型应用场景 |
|---|---|---|---|---|
append() |
单个元素 | 原地修改 | None | 逐步构建研究数据库 |
extend() |
多个元素 | 原地修改 | None | 合并多来源的考古数据 |
在列表创建后,可以通过元素赋值的方式修改列表中的元素。一般情况下,赋值语句左边是一个变量名。但是,也可以使用列表的下标来改变下标处的值。
# 编号,典籍名称,借阅次数(千次),馆藏数量(千册),研究热度指数,保护等级评分
cultural_heritage = ['B0017', '《敦煌遗书》', 15.8, 15.9, 95.0, 14.5]
# 更新研究热度指数(原最高价字段位置)
cultural_heritage[4] = 100.0
print(cultural_heritage)
# 输出:['B0017', '《敦煌遗书》', 15.8, 15.9, 100.0, 14.5]
['B0017', '《敦煌遗书》', 15.8, 15.9, 100.0, 14.5]
应用场景:文化遗产数据修正或作废
# 原始殷墟甲骨研究数据(含伪造记录)
artifact_data = ['A0032', '殷墟甲骨', 8.6, 2.3, 88.0, 14.8, '出土方位假数据']
# 方法1:del语句删除错误数据
del artifact_data[6]
print(f"修正后数据:{artifact_data}")
# 输出:['A0032', '殷墟甲骨', 8.6, 2.3, 88.0, 14.8]
artifact_data = ['A0032', '殷墟甲骨', 8.6, 2.3, 88.0, 14.8, '出土方位假数据']
# 方法1:del语句删除错误数据
del artifact_data[6]
print(f"修正后数据:{artifact_data}")
修正后数据:['A0032', '殷墟甲骨', 8.6, 2.3, 88.0, 14.8]
# 考古发现临时数据管理
excavation_data = ["A001", "青铜器", 15.6, "商代", "需复核"]
# 移除并保存需复核标记
check_flag = excavation_data.pop()
print(f"撤回标记:{check_flag} → 进入复核流程")
# 输出:撤回标记:需复核 → 进入复核流程
print("当前有效数据:", excavation_data)
# 输出:['A001', '青铜器', 15.6, '商代']
撤回标记:需复核 → 进入复核流程 当前有效数据: ['A001', '青铜器', 15.6, '商代']
# 方法2:pop()提取复核数据
# 原始殷墟甲骨研究数据(含伪造记录)
artifact_data = ['A0032', '殷墟甲骨', 8.6, 2.3, 88.0, 14.8, '出土方位假数据']
preserve_score = artifact_data.pop(5)
print(f"已提取保护评分:{preserve_score} → 待提交UNESCO复核")
# 输出:已提取保护评分:14.8 → 待提交UNESCO复核
artifact_data = ['A0032', '殷墟甲骨', 8.6, 2.3, 88.0, 14.8, '出土方位假数据']
pop_data = artifact_data.pop()
print(pop_data)
artifact_data
出土方位假数据
['A0032', '殷墟甲骨', 8.6, 2.3, 88.0, 14.8]
操作要点:
del适用场景 → 永久删除无效数据(如错误文献版本)pop()适用场景 → 临时撤回待审核指标(如争议性保护等级)应用场景:古籍数字化工程批量更新
# 《永乐大典》数据更新
yongle_dadian = ['C0125', '《永乐大典》', 3.2, 0.4, 92.5, 12.0]
# 批量更新字段(索引2-5)
yongle_dadian[2:6] = [5.7, 1.2, 97.8, 15.0]
print(f"更新后:{yongle_dadian}")
# 输出:['C0125', '《永乐大典》', 5.7, 1.2, 97.8, 15.0]
# 《永乐大典》数据更新
yongle_dadian = ['C0125', '《永乐大典》', 3.2, 0.4, 92.5, 12.0]
# 批量更新字段(索引2-5)
yongle_dadian[2:6] = [5.7, 1.2, 97.8, 15.0]
print(f"更新后:{yongle_dadian}")
更新后:['C0125', '《永乐大典》', 5.7, 1.2, 97.8, 15.0]
# 插入修复进度字段
yongle_dadian[5:5] = [75.4]
print(f"新增修复进度:{yongle_dadian}")
# 输出:['C0125', '《永乐大典》', 5.7, 1.2, 97.8, 75.4, 15.0]
yongle_dadian[5:5] = [75.4]
print(f"新增修复进度:{yongle_dadian}")
新增修复进度:['C0125', '《永乐大典》', 5.7, 1.2, 97.8, 75.4, 75.4, 15.0]
字段变化:
原始结构 → [编号, 名称, 借阅次数, 馆藏量, 研究热度, 保护等级]
更新后结构 → [编号, 名称, 借阅次数, 馆藏量, 研究热度, 修复进度, 保护等级]
应用场景:跨学科参数调整
# 莫高窟壁画保护参数
[编号, 名称, 湿度阈值, 温度阈值] = ["M0823", "飞天壁画", 45.0, 22.5]
# 原子级参数调整
湿度阈值, 温度阈值 = 42.0, 20.0
print(f"新标准:湿度{湿度阈值}% / 温度{温度阈值}℃")
[编号, 名称, 湿度阈值, 温度阈值] = ["M0823", "飞天壁画", 45.0, 22.5]
# 原子级参数调整
湿度阈值, 温度阈值 = 42.0, 20.0
print(f"新标准:湿度{湿度阈值}% / 温度{温度阈值}℃")
新标准:湿度42.0% / 温度20.0℃
# 云锦研究优先级修正
yunjin_data = ["NJ074", "云锦织造", "工艺研究", "经济价值"]
yunjin_data[2], yunjin_data[3] = yunjin_data[3], yunjin_data[2]
print(f"修正后:{yunjin_data}")
# 输出:["NJ074", "云锦织造", "经济价值", "工艺研究"]
yunjin_data = ["NJ074", "云锦织造", "工艺研究", "经济价值"]
yunjin_data[2], yunjin_data[3] = yunjin_data[3], yunjin_data[2]
print(f"修正后:{yunjin_data}")
修正后:['NJ074', '云锦织造', '经济价值', '工艺研究']
在Python中,星号(*)用于解构赋值时,可以收集多个元素到列表变量中。当左侧变量中有且仅有一个星号变量时,它会匹配未被其他变量捕获的剩余元素。具体规则如下:
# 考古记录解构
记录条目 = ["青铜器", "陶器", "玉器", "甲骨", 689, "2023-09"]
*器物类型, 总件数, 记录日期 = 记录条目
print(f"器物类型:{器物类型}") # ['青铜器', '陶器', '玉器', '甲骨']
print(f"统计:{总件数}件 @ {记录日期}")
变量匹配逻辑:
右侧列表 记录条目 包含6个元素。 左侧的 总件数 和 记录日期 对应最后两个元素(689 和 "2023-09")。 剩余的4个元素("青铜器", "陶器", "玉器", "甲骨")会被星号变量 *器物类型 收集成一个列表。
记录条目 = ["青铜器", "陶器", "玉器", "甲骨", 689, "2023-09"]
*器物类型, 总件数, 记录日期 = 记录条目
print(f"器物类型:{器物类型}") # ['青铜器', '陶器', '玉器', '甲骨']
print(f"统计:{总件数}件 @ {记录日期}")
器物类型:['青铜器', '陶器', '玉器', '甲骨'] 统计:689件 @ 2023-09
| 操作类型 | 人文场景案例 | 技术要点 | 注意事项 |
|---|---|---|---|
| 元素删除 | 撤回争议考古数据 | pop()保持操作可逆性 |
确认有效性再使用del |
| 分片赋值 | 古籍元数据批量更新 | 索引范围精准控制 | 防止字段语义错位 |
| 多重赋值 | 文物保护参数同步 | 元组解包实现原子操作 | 避免混合数据类型 |
实践建议:尝试修改敦煌遗书案例中的研究热度指数,观察不同操作方法对数据完整性的影响
# 访问第一个元素(索引从0开始)
print("第一门课程是:", courses[0])
# 添加一门新课程
courses.append("心理学")
print("添加后课程列表:", courses)
# 删除一门课程
courses.remove("哲学")
print("删除'哲学'后的课程列表:", courses)
# 修改课程名称
courses[1] = "古典文学"
print("修改后的课程列表:", courses)
# 课程总数
print("总共有", len(courses), "门课程")
第一门课程是: 历史 添加后课程列表: ['历史', '哲学', '文学', '语言学', '社会学', '心理学'] 删除'哲学'后的课程列表: ['历史', '文学', '语言学', '社会学', '心理学'] 修改后的课程列表: ['历史', '古典文学', '语言学', '社会学', '心理学'] 总共有 5 门课程
| 函数/操作 | 解释说明 | 人文社科应用示例 |
|---|---|---|
append(x) |
在列表末尾添加元素 | research_topics.append("非遗保护") → 新增研究方向 |
insert(i, x) |
在索引i处插入元素 | archive_list.insert(2, "西夏文书") → 插入第二顺位文献 |
remove(x) |
删除第一个匹配元素 | excavation_items.remove("赝品陶器") → 剔除伪造文物 |
pop([i]) |
删除并返回索引i的元素(默认末尾) | preserve_levels.pop(3) → 撤回第4项保护等级数据 |
sort() |
原地排序(可指定key和reverse) | research_team.sort(key=lambda x: x[1]) → 按姓名排序 |
reverse() |
反转列表元素顺序 | chronology.reverse() → 将纪年表改为倒序排列 |
extend(iterable) |
追加可迭代对象的所有元素 | dig_sites.extend(["三星堆", "良渚"]) → 合并考古遗址 |
index(x) |
返回元素x的首次出现索引 | literature.index("《史记》") → 查找典籍位置 |
count(x) |
统计元素x的出现次数 | folk_arts.count("剪纸") → 统计民俗技艺数量 |
copy() |
创建列表的浅拷贝 | new_list = artifacts.copy() → 保护原始数据不被修改 |
clear() |
移除所有元素 | temp_survey.clear() → 清空临时田野调查数据 |
数值的列表或字符串的列表,能用sort()方法排序。sort()方法当场对列表排序:
stock_list = ['600000','600036','000001','300142','600048']
stock_list.sort() # 默认升序排列
stock_list
['000001', '300142', '600000', '600036', '600048']
help(stock_list.sort)
Help on built-in function sort:
sort(*, key=None, reverse=False) method of builtins.list instance
Sort the list in ascending order and return None.
The sort is in-place (i.e. the list itself is modified) and stable (i.e. the
order of two equal elements is maintained).
If a key function is given, apply it once to each list item and sort them,
ascending or descending, according to their function values.
The reverse flag can be set to sort in descending order.
也可以指定reverse关键字参数为True,让sort()按逆序排序。
stock_list.sort(reverse=True)
stock_list
['600048', '600036', '600000', '300142', '000001']
不能对既有数字又有字符串值的列表排序,因为Python 不知道如何比较它们。
moreList = stock_list + list(range(5))
moreList
['600048', '600036', '600000', '300142', '000001', 0, 1, 2, 3, 4]
moreList.sort()
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) ~\AppData\Local\Temp\ipykernel_20940\3612116042.py in <module> ----> 1 moreList.sort() TypeError: '<' not supported between instances of 'int' and 'str'
sort()方法对字符串排序时,使用“ASCII 字符顺序”,而不是实际的字典顺序。这意味着大写字母排在小写字母之前。因此在排序时,小写的a 在大写的
Z 之后:
someWords = ['Alice', 'ants', 'Bob', 'badgers', 'Carol', 'cats']
someWords
['Alice', 'ants', 'Bob', 'badgers', 'Carol', 'cats']
someWords.sort()
someWords
['Alice', 'Bob', 'Carol', 'ants', 'badgers', 'cats']
someWords
扩展
sort()方法有一个key的关键字参数,可以指定排序方法,例如:
someWords = ['Alice', 'ants', 'Bob', 'badgers', 'Carol', 'cats']
someWords
['Alice', 'ants', 'Bob', 'badgers', 'Carol', 'cats']
someWords.sort(key=len)
someWords #按照每一项的长度进行排序
['Bob', 'ants', 'cats', 'Alice', 'Carol', 'badgers']
【课堂练习】
有5个人竞拍,按照规则,出价最高者获得拍卖品。编写程序,由5个人分别输入他们的名字和竞拍价,最后打印出获得拍卖品者的名字和价格。</font>
注:名字和竞拍价之间用逗号隔开。
result = []
result.append(input("请输入您的名字和竞拍价:").split(","))
result.append(input("请输入您的名字和竞拍价:").split(","))
result.append(input("请输入您的名字和竞拍价:").split(","))
result.append(input("请输入您的名字和竞拍价:").split(","))
result.append(input("请输入您的名字和竞拍价:").split(","))
result[0] = [float(result[0][1]), result[0][0]]
result[1] = [float(result[1][1]), result[1][0]]
result[2] = [float(result[2][1]), result[2][0]]
result[3] = [float(result[3][1]), result[3][0]]
result[4] = [float(result[4][1]), result[4][0]]
result.sort(reverse=True)
print("获得拍卖品的是:{},出价为:{:.2f}元".format(result[0][1], result[0][0]))
| 函数/操作 | 解释说明 | 人文社科应用示例 |
|---|---|---|
| 列表推导式 | 创建新列表的简洁语法 | [x*2 for x in funding] → 生成双倍经费模拟方案 |
in操作符 |
成员关系判断 | "甲骨文" in research_list → 验证是否包含研究方向 |
len() |
返回列表元素数量 | len(ancient_books) → 获取馆藏古籍总量 |
max()/min() |
返回最大/最小值 | max(research_impact) → 找出最高研究影响力指标 |
sum() |
对数值元素求和 | sum(project_budgets) → 计算科研经费总额 |
sorted() |
返回新排序列表 | sorted(preserve_levels, reverse=True) → 保护等级降序 |
| 切片操作 | 获取子列表 | cultural_sites[2:5] → 提取第3-5个文化遗产地 |
enumerate() |
获取带索引的迭代器 | for i, item in enumerate(excavations) → 考古发现编号 |
zip() |
并行迭代多个列表 | for name, level in zip(sites, scores) → 配对遗址与评分 |
filter() |
筛选满足条件的元素 | list(filter(lambda x: x>50, heat_values)) → 筛选高热度研究 |
map() |
对每个元素应用函数 | list(map(int, protect_years)) → 转换保护年限为整型 |
## 使用范例
# 口述史访谈记录整理
interviewees = ["张先生", "王女士", "李教授"]
interviewees.append("周馆长") # 新增受访者
# 考古发现年代修正
carbon_dating = [1023, 845, 1560]
carbon_dating.insert(1, 920) # 在第二位插入新测年数据
# 非物质文化遗产筛选
i = ["剪纸", "皮影", "刺绣"].index("皮影") # 查找传统技艺位置
# 生成研究影响力Top5
sorted([78, 92, 85, 95, 88], reverse=True)[:5] # [95, 92, 88, 85, 78]
[95, 92, 88, 85, 78]
假设我们分析一位学生在一周内阅读的书籍,可以用列表来表示每天读的书籍标题。
# 学生每一天读的一本书
reading_log = ["红楼梦", "论语", "史记", "庄子", "围城", "呐喊", "边城"]
# 统计一周共读了几本书
print("一周共读了", len(reading_log), "本书")
# 显示周三读的是哪本书(索引2)
print("周三读的是:", reading_log[2])
一周共读了 7 本书 周三读的是: 史记
# 请在下方写出你的答案 👇
# 示例:
my_books = ["活着", "百年孤独", "追风筝的人", "许三观卖血记", "沉默的大多数"]
# 添加一本新书
my_books.append("围城")
# 删除一本不太喜欢的
my_books.remove("许三观卖血记")
# 修改书名
my_books[2] = "小王子"
# 打印结果
print("现在的书单:", my_books)
print("书单长度为:", len(my_books))
|
【课堂提问】 1. 列表的`append`方法和`extend`方法的区别是什么? 2. 列表删除元素的方法有哪些? |
列表是一个值,它包含多个值构成的序列。术语“列表值”指的是列表本身(它作为一个值,可以保存在变量中,或传递给函数,像所有其他值一样),而不是指列表值之内的那些值。
列表值看起来像这样:['四川外国语大学', '重庆大学', '西南大学', '西南政法大学']。
就像字符串值用引号来标记字符串的起止一样,列表用左方括号开始,右方括号结束,即[ ]。列表中的值也称为“表项”。表项用逗号分隔(就是说,它们是“逗号分隔的”)。
列表的长度和内容都是可变的,可自由对列表中数据项进行增加、删除或替换。列表没有长度限制,元素类型可以不同,使用非常灵活。
由于列表属于序列类型,所以列表也支持成员关系操作符(in)、长度计算函数(len())、分片([])。
列表可以同时使用正向递增序号和反向递减序号,可以采用标准的比较操作符(<、<=、==、!=、>=、>)进行比较,列表的比较实际上是单个数据项的逐个比较。
列表的操作
| 函数或方法 | 描述 | |
|---|---|---|
| ls[i] = x | 替换列表ls第i数据项为x | |
| ls[i: j] = lt | 用列表lt替换列表ls中第i到j项数据(不含第j项,下同) | |
| ls[i: j: k] = lt | 用列表lt替换列表ls中第i到j以k为步的数据 | |
| del ls[i: j] | 删除列表ls第i到j项数据,等价于ls[i: j]=[] | |
| del ls[i: j: k] | 删除列表ls第i到j以k为步的数据 | |
| ls += lt或ls.extend(lt) | 将列表lt元素增加到列表ls中 | |
| ls *= n | 更新列表ls,其元素重复n次 | |
| ls.append(x) | 在列表ls最后增加一个元素x | |
| ls.clear() | 删除ls中所有元素 | |
| ls.copy() | 生成一个新列表,复制ls中所有元素 | |
| ls.insert(i, x) | 在列表ls第i位置增加元素x | |
| ls.pop(i) | 将列表ls中第i项元素取出并删除该元素 | |
| ls.remove(x) | 将列表中出现的第一个元素x删除 | |
| ls.reverse() | 列表ls中元素反转 | |
| ls.index(x) | 找出某个值第一个匹配项的索引位置 |