列表的扩展操作
zip() 函数
我们先学习 zip()
函数,将排名与分数挂钩。
还记得期中考试的顺序排名和分数吗?我们把排名放在了列表 midterm_rank
中,把分数放在了 scores
中。不过当时 scores
并没有排序,我们要对数据进行预处理,让其与 midterm_rank
的排序逻辑一致。
我们将 scores
中的分数通过 sort()
与 reverse()
从小到大排序再倒转的方式实现。
midterm_rank = ['妙玉', '薛宝钗', '贾元春', '王熙凤', '林黛玉', '贾巧姐', '史湘云','贾迎春', '贾宝玉', '李纨', '贾探春', '秦可卿', '贾惜春', '贾琏'
]scores = [100, 92, 77, 85, 81, 90, 100, 86, 79, 93, 91, 96, 75, 84]# 将 scores 元素从低到高排列
scores.sort()# 倒转 scores 中的排列顺序
scores.reverse()print(scores)
# 输出:[100, 100, 96, 93, 92, 91, 90, 86, 85, 84, 81, 79, 77, 75]
接下来就是 zip()
函数上场的时间啦。它的作用是将两个长度相同的列表合并起来,相同位置的元素会被一一组对,变成一个元组。结果返回一个组合好的打包对象,需要我们再用 list()
函数转换回列表。
哎?上面的话是不是有点啰嗦呀,让我 show you the code 吧。
# 用 zip() 将两个列表合并
zipped = zip(midterm_rank, scores)# 将结果转换回列表后,赋值给 zipped_rank
zipped_rank = list(zipped)# 来看看结果
print(zipped_rank)
# 输出:[('妙玉', 100), ('薛宝钗', 100), ('贾元春', 96), ('王熙凤', 93), ('林黛玉', 92), ('贾巧姐', 91), ('史湘云', 90), ('贾迎春', 86), ('贾宝玉', 85), ('李纨', 84), ('贾探春', 81), ('秦可卿', 79), ('贾惜春', 77), ('贾琏', 75)]
我们看到,列表 zipped_rank
是一个嵌套结构,其中每个元素是一个元组,每个元组中是原来两个列表中对应位置的元素。
大家看懂 zip()
的操作逻辑了吗?zip()
是一个很形象的函数。因为单词“zip”的原义就是“拉链”,将左右两边链条中的同一位置的链齿压到一起,最后合并成一整个链条。
通过 zip()
这个“拉链”,我们成功将同学们的排名和他们对应的分数绑定到了一起,这样就可以更直观地分析他们的成绩啦。
enumerate() 函数
enumerate()
函数最难的地方,可能不是用法,而是这个函数名……可能是目前我们学起来最难背的英文单词之一啦。
“enumerate”单词本身意思是“枚举、数数”。所以对应的函数功能,就是一个一个地将列表中的元素数出来。它返回的是一个枚举对象,也需要我们用 list()
函数转换回列表。
有了这个函数,我们就可以把原来的排名表 midterm_rank
中,每个同学的具体排名都显示出来了。
但是要注意:机器还是会从 0
开始数……
# 枚举原排名表后,再转回列表的形式
rank_with_id = list(enumerate(midterm_rank))print(rank_with_id)
# 输出:[(0, '妙玉'), (1, '薛宝钗'), (2, '贾元春'), (3, '王熙凤'), (4, '林黛玉'), (5, '贾巧姐'), (6, '史湘云'), (7, '贾迎春'), (8, '贾宝玉'), (9, '李纨'), (10, '贾探春'), (11, '秦可卿'), (12, '贾惜春'), (13, '贾琏')]
我们看到,最后的结果是与 zip()
处理结果相似的嵌套结构,列表中每个元素是一个元组,元组中是排名和姓名。
毕竟结果是要在现实世界中使用的,从 0
开始数的排名实在不太符合我们实际使用的要求。好在 enumerate()
函数中有个默认参数表示起始数字,默认为 0
,所以机器才会从 0
开始数。我们可以手动输入起始数字 1
,让结果更符合我们的习惯。
# enumerate()中这次有两个参数,一个为排名列表,一个为起始数字。
rank_with_id = list(enumerate(midterm_rank, 1))print(rank_with_id)
# 输出:[(1, '妙玉'), (2, '薛宝钗'), (3, '贾元春'), (4, '王熙凤'), (5, '林黛玉'), (6, '贾巧姐'), (7, '史湘云'), (8, '贾迎春'), (9, '贾宝玉'), (10, '李纨'), (11, '贾探春'), (12, '秦可卿'), (13, '贾惜春'), (14, '贾琏')]
有了 zip()
和 enumerate()
函数,我们就能给列表中的每个元素附加更多的信息,方便我们查看与操作。我们之后会学到“循环”的知识,进一步了解这两个函数的作用。
另外,生成的这种嵌套结构,我们称为“二维列表”,下一关会详细讲解它的用法哦。
那么下面,我们用一个小练习,来巩固本小节的知识吧。
本章练习:
练习一:
《红楼梦》是我们四大名著之一,也是我国文学史上是最巅峰之作。作者是曹雪芹先生,也是贾宝玉的原型。
我们知道,四大名著的其它三本分别是罗贯中的《三国演义》,施耐庵的《水浒传》,以及吴承恩的《西游记》。
我们用两个列表来分别储存书名和作者:
books = ['红楼梦', '三国演义', '水浒传', '西游记']
authors = ['曹雪芹', '罗贯中', '施耐庵', '吴承恩']
你可以用我们刚刚学过的知识,将书名和作者绑定起来吗?
另外,在小贝心目中,四大名著的地位排序是:《三国演义》《西游记》《红楼梦》《水浒传》,他将四本书按他心目中的顺序录进了列表 books_favorite
中。我们能用用刚刚学过的代码帮他对 books_favorite
进行操作,附上数字表示的排名吗?
要求:
- 用
zip()
函数将books
和authors
以“著作名,作者”的形式结合成新列表。并将结果打印在屏幕上。 - 新建
books_favorite
列表,按小贝喜爱的顺序排列四本书。 - 用
enumerate()
函数,从1
开始,枚举books_favorite
列表,将结果打印在屏幕上。
books = ['红楼梦', '三国演义', '水浒传', '西游记']
authors = ['曹雪芹', '罗贯中', '施耐庵', '吴承恩']# 用 zip() 将两个列表绑定
zip = zip(books,authors)# 转换回列表后打印绑定结果
print(list(zip))# 新建 books_favorite 列表,顺序按小贝的喜好来
books_favorite = ['三国演义', '西游记', '红楼梦', '水浒传']# 用 enumerate() 函数枚举结果,从 1 开始
favorite = enumerate(books_favorite, 1)# 转换回列表后打印结果
print(list(favorite))
今天学习了这么多知识,我越来越钦佩坚持的你。我们来梳理一下今日所学。
在 列表基本运算 一节,我们用 in
判断列表中是否包含某一元素,用 +
将两个列表链接在一起,用 *
将列表元素重复多次生成新列表。
我们学习了新的数据类型——元组,它和列表很相似,但是不支持元素的修改,但支持元素的查询及分片,也支持上面说的三种运算。
zip()
函数 可以合并两个列表,将两个列表中一一对应的元素合并到一个元组中,从而生成一个新的 zip
类型。在 Python 3 中,需要用 list() 函数将上述两种类型转化为列表。
enumerate()
函数 可以给列表中每个元素加上序号,合并到一个元组中,从而生成一个新的 enumerate
类型,同样需要用 list()
函数将其转化为列表。
练习二:
体育老师为要测试金陵十二钗的体育成绩,于是组织她们进行了一次立定跳远测试。老师将她们分成三组,每组四个人,分别记录她们的成绩(单位厘米),储存在列表 group1
, group2
, group3
中。
现体育老师在要对三组的数据汇总,从高到低排列并附上排名,你能帮帮他吗?
要求:
- 将题目中的
group1
、group2
、group3
合并在一起; - 对合并后的成绩从高到低排序;
- 用
enumerate()
函数将排序后的列表从1
开始枚举,将结果储存在列表run_rank
中; - 打印出
run_rank
。group1 = [198, 133, 154, 166] group2 = [188, 172, 119, 142] group3 = [168, 153, 131, 128]# 将三组的成绩合并到一起 group = group1 + group2 + group3 # 对合并后的成绩从低到高排序 group.sort() # 反转——对合并后的成绩从高到低排序 group.reverse()# 将合并后的成绩用数字枚举出来,并转换成列表放进 run_rank 中 run_rank = list(enumerate(group, 1))# 打印最后的排名和成绩 print(run_rank)
练习三:
谁是 Top3?
期中考试过后,老师将排名以先后顺序储存在了列表 midterm_rank
中,接下来需要你来帮帮忙,用代码帮老师筛选出这次考试的前三名,并把对应的名次标注上。最终应打印出如下的内容,快来动手试试吧~
[(1, '妙玉'), (2, '薛宝钗'), (3, '贾元春')]
答:
midterm_rank = ['妙玉', '薛宝钗', '贾元春', '王熙凤', '林黛玉', '贾巧姐', '史湘云','贾迎春', '贾宝玉', '李纨', '贾探春', '秦可卿', '贾惜春', '贾琏'
]# 解答一:
rank = midterm_rank[:3]
list = list(enumerate(rank, 1))# 解答二
# rank = midterm_rank[:3]
# list = list(enumerate(rank, 1))
print(list)
练习四:
闻闻使用 Python 记录了自己的书单,总共有两份。现在,让我们对闻闻的书单进行简单的处理。
我们总共需要做两件事:
- 将两份书单合并;
- 写一个查询书籍是否在书单里的函数
check_book()
,如果在就打印出 已查询到xxx,否则打印出 未查询到xxx(xxx 为要查询的书名)。
books1 = ['活着', '围城', '平凡的世界', '骆驼祥子']
books2 = ['边城', '城南旧事', '撒哈拉的故事', '三体全集']# 合并两个书单
books = books1 + books2def check_book(name):if name in books:print('已查询到', name)else:print('未查询到', name)check_book('边城')
check_book('红楼梦')