Kodewick
第 9 课,共 31 课目录

列表

第 9 课,共 31 课 · 第 2 部分 · 容器和循环 · 约 20 分钟

一个变量放一个值;一个列表能按顺序放很多个值,共用一个名字。把各项写在方括号里,用逗号隔开。len() 告诉你有几项,和字符串一样。

main.py
1streets = ["磨坊巷", "池塘路", "山坡街"]2print(streets)3print(len(streets))4mixed = ["Wick", 7, True, 2.5]5print(mixed, len(mixed))6print([], len([]))
输出
['磨坊巷', '池塘路', '山坡街']
3
['Wick', 7, True, 2.5] 4
[] 0

列表里什么值都能放:数字、字符串、布尔值,混在一起也行。[] 是空列表,里面还什么都没有。

下标和切片

列表的下标和切片和字符串一样。第一项的下标是 0;-1 是最后一项。切片 [start:stop] 得到一个新列表,从 start 开始,到 stop 之前为止,不包括 stop。

main.py
1ore = ["煤", "铁", "铜", "金", "银"]2print(ore[0])3print(ore[-1])4print(ore[1:3])5print(ore[:2])6print(ore[::-1])
输出
煤
银
['铁', '铜']
['煤', '铁']
['银', '金', '铜', '铁', '煤']

要一个不存在的下标,Python 会停下来,报 IndexError。五项的列表,下标是 0 到 4。

main.py
1ore = ["煤", "铁", "铜", "金", "银"]2print(ore[4])3print(ore[5])
输出
银
Traceback (most recent call last):
  File "main.py", line 3, in <module>
    print(ore[5])
IndexError: list index out of range

发生了什么: 下标超出范围了:这里面没有那么多个。别忘了下标从 0 开始数。

列表可以改

字符串不能改,列表可以。用 = 给某个下标放一个新值。要加东西,用列表的方法:append 在末尾加一项,insert 在某个下标插入一项,extend 把另一个列表的每一项都加进来。

main.py
1houses = ["红", "蓝", "绿"]2houses[1] = "黄"3print(houses)4houses.append("白")5print(houses)6houses.insert(0, "黑")7print(houses)8houses.extend(["粉", "灰"])9print(houses)
输出
['红', '黄', '绿']
['红', '黄', '绿', '白']
['黑', '红', '黄', '绿', '白']
['黑', '红', '黄', '绿', '白', '粉', '灰']

这些方法改的是列表本身,不会造一个新列表,所以不用再赋值:写 houses.append("白"),不要写 houses = houses.append("白")。

先猜一猜

这段会显示什么?

1a = [1, 2]2a.append([3, 4])3print(len(a))

+ 把两个列表接成一个新列表,* 把列表重复几遍,和字符串一样。

删除

从列表里拿掉东西有好几种办法。看你知道的是什么:是值,还是位置。

main.py
1tools = ["镐", "灯", "绳子", "地图", "灯"]2tools.remove("灯")3print(tools)4last = tools.pop()5print(last, tools)6first = tools.pop(0)7print(first, tools)8del tools[0]9print(tools)
输出
['镐', '绳子', '地图', '灯']
灯 ['镐', '绳子', '地图']
镐 ['绳子', '地图']
['地图']
  • remove(x) 删掉第一个等于 x 的项。第二个 "灯" 还在。
  • pop() 拿出最后一项并返回它;pop(i) 拿的是下标 i 那一项。
  • del 列表[i] 删掉下标 i 那一项。clear() 把整个列表清空。

remove 一个不在列表里的值会报错:ValueError。拿不准的话,先用 in 查一下。

查找

in 问的是「这个值在不在列表里」,得到 True 或 False。index(x) 给出第一个 x 的位置;count(x) 数 x 出现了几次。

main.py
1crates = ["铁", "煤", "铁", "金", "铁"]2print("金" in crates)3print("银" in crates)4print(crates.index("金"))5print(crates.count("铁"))6if "煤" in crates:7    print("煤在", crates.index("煤"))
输出
True
False
3
3
煤在 1

排序

sort() 把列表排好,改的是列表本身。sorted(列表) 不动原来的列表,返回一个排好的新列表。两个都能加 reverse=True,从大到小排。字符串按字母排,大写字母排在小写前面;汉字按编码排,不是按拼音或笔画。

main.py
1weights = [7, 2, 9, 4]2print(sorted(weights))3print(weights)4weights.sort(reverse=True)5print(weights)6names = ["wick", "Ada", "bo", "Cy"]7print(sorted(names))
输出
[2, 4, 7, 9]
[7, 2, 9, 4]
[9, 7, 4, 2]
['Ada', 'Cy', 'bo', 'wick']
先猜一猜

这段会显示什么?

1nums = [3, 1, 2]2result = nums.sort()3print(result)

reverse() 把列表就地倒过来,不排序。

数字列表

学数字时见过的 sum、min、max 也能用在列表上。再加上 len,就能算平均数。

main.py
1ore_per_day = [12, 8, 15, 10, 5]2total = sum(ore_per_day)3print(f"总共:{total}")4print(f"最多的一天:{max(ore_per_day)}")5print(f"最少的一天:{min(ore_per_day)}")6print(f"平均:{total / len(ore_per_day)}")
输出
总共:50
最多的一天:15
最少的一天:5
平均:10.0

复制列表

b = a 不是复制列表,而是给同一个列表多起一个名字。通过一个名字改了它,用另一个名字也能看到。第 2 课里,a = 9 是让 a 指向一个新值,b 不受影响;b.append(...) 不一样,它改的是两个名字共用的那一个列表。点单步看看:两个名字指着同一个列表。

main.py
1a = ["灯", "绳子"]2b = a3b.append("地图")4print(a)5c = a.copy()6c.append("镐")7print(a)8print(c)
输出
['灯', '绳子', '地图']
['灯', '绳子', '地图']
['灯', '绳子', '地图', '镐']

a.copy() 造一个新的、单独的列表,里面的项一样;切片 a[:] 也是。改副本,原来的列表不变。

小技巧: 列表「自己变了」的时候,往前找找有没有 b = a 这样的一行。

列表和别的类型

list() 能把别的东西变成列表:字符串会变成一个个字符。split 把字符串切成一个词的列表,join 再把字符串列表粘回一个字符串。

main.py
1print(list("灯火通明"))2words = "煤 铁 金".split()3print(words)4print(" + ".join(words))5nums = "4,8,15".split(",")6print(nums)7print(int(nums[0]) + int(nums[1]))
输出
['灯', '火', '通', '明']
['煤', '铁', '金']
煤 + 铁 + 金
['4', '8', '15']
12

split 切出来的是字符串,要先用 int() 转成数字才能算。

方法一览

写法作用
a.append(x)在末尾加上 x
a.insert(i, x)把 x 插到下标 i
a.extend(b)把 b 的每一项加到末尾
a.remove(x)删掉第一个 x(没有就报 ValueError)
a.pop() / a.pop(i)拿出并返回最后一项 / 第 i 项
del a[i]删掉第 i 项
a.clear()全部删掉
a.index(x)第一个 x 的位置
a.count(x)x 出现了几次
a.sort() / sorted(a)就地排序 / 返回排好的新列表
a.reverse()就地倒过来
a.copy()一个项相同的新列表

练一练

写好代码,点检查。提示随便看,实在想不出来再看答案。

练习 1

理顺路线

Wick 的路线顺序不对,还少了一站。改一改列表,让它显示下面这样。街名用的是英文:英文按字母排得清楚,汉字按编码排,不是按拼音。

要显示
['Mill Lane', 'Pond Road', 'Hill Street']
exercise1.py
1route = ["Pond Road", "Mill Lane"]2# 在这里写3print(route)
输出
点「运行」或按 Ctrl+Enter
练习 2

最好的三天

显示列表里最大的三个数,从大到小,不要改动 ore。

要显示
[15, 14, 12]
exercise2.py
1ore = [12, 8, 15, 10, 5, 14]2# 在这里写
输出
点「运行」或按 Ctrl+Enter
练习 3

保住原来的

这段程序本来想让 stock 保持原样,可最后一行显示 stock 也变了。改一行。

要显示
['煤', '铁', '金']
['煤', '铁']
exercise3.py
1stock = ["煤", "铁"]2order = stock3order.append("金")4print(order)5print(stock)
输出
点「运行」或按 Ctrl+Enter

这一课学会了

  • 列表按顺序放很多个值:[1, 2, 3]。len() 数有几项;[] 是空列表。
  • 下标和切片和字符串一样;下标不存在会报 IndexError。
  • 列表可以改:a[i] = x、append、insert、extend、remove、pop、del。
  • in、index、count 用来查找;sort() 改列表本身,sorted() 给一个新的。
  • sum、min、max 能用在数字列表上。
  • b = a 是一个列表两个名字;a.copy() 才是真的复制。