🐸 青蛙编程网
首页 / Python / Python 基础 / 6. 列表与字典

列表与字典

这是什么:列表(list) = 按顺序排好队的一串值,用 [] 装;字典(dict) = 一组「键 → 值」的对应关系,用 {} 装。

为什么用:到目前为止,一个变量只能装一个值。要记全班 40 个成绩,难道起 40 个名字?有了列表和字典,一个变量就装得下一整车数据。

如何用:本章用 fruits 列表练增删改查和切片,再用一个「商品 → 价格」的字典练取值和遍历。

列表:排好队的一组值

方括号把值排成一队,逗号隔开,增删改查都方便:

fruits = ["苹果", "香蕉", "橘子"]

fruits.append("葡萄")     # 增:加到队尾
fruits[0] = "红苹果"      # 改:按位置替换
del fruits[1]             # 删:删掉"香蕉"

print(fruits)             # 查:整个列表
print(fruits[-1])         # -1 表示最后一个
print(fruits[1:3])        # 切片:取第 1 到第 2 个(不含 3)
print(len(fruits))        # 一共几个

你会看到:

['红苹果', '橘子', '葡萄']
葡萄
['橘子', '葡萄']
3

重点:位置从 0 开始数,fruits[0] 才是第一个——这是新手第二大坑(第一大还是中文引号)。切片和 range 一样含头不含尾。

挨个处理叫遍历,for 循环一步到位:

fruits = ["红苹果", "橘子", "葡萄"]

for f in fruits:
    print("今天吃", f)

你会看到:

今天吃 红苹果
今天吃 橘子
今天吃 葡萄

字典:按名字找值

列表靠位置找值,字典靠键(key)找值——真像查字典:按"字"翻到"释义":

frog = {"名字": "小绿", "年龄": 3, "会游泳": True}

frog["爱好"] = "吃虫子"   # 增:键不存在,就是新增
frog["年龄"] = 4          # 改:键已存在,就是覆盖
del frog["会游泳"]        # 删:连键带值一起删

print(frog["名字"])       # 查:按键取值

for key, value in frog.items():
    print(key, "→", value)

你会看到:

小绿
名字 → 小绿
年龄 → 4
爱好 → 吃虫子

注意:查一个不存在的键(比如 frog["体重"])会直接报 KeyError。拿不准就先问一句:if "体重" in frog:。

何时用哪个

场景 用什么
一组有顺序的同类东西:成绩单、待办清单 列表 []
描述一件事的多条属性:一只蛙的名字、年龄、爱好 字典 {}
要按位置取值("第 3 个") 列表
要按名字取值("年龄是多少") 字典

记忆口诀

列表按号排队,字典点名签到;位置从 0 起,切片含头不含尾。

⚠️ 新手翻车现场

翻车一:索引越界

fruits = ["苹果", "香蕉", "橘子"]
print(fruits[3])
IndexError: list index out of range

逐行分析:第 1 行登记了 3 个元素,没问题;第 2 行出事——你心里想的是"取第 3 个",但列表位置从 0 起数,3 个元素的位置只有 0、1、2,fruits[3] 实际是"第 4 个",一伸手就伸进了空处。Python 怎么发现的?取值那一刻它会先核对下标是否在 0~2 的范围内,越界就抛 IndexError: list index out of range(下标越界)。好消息:这类错报得快、指得准,顺着报错行就能定位。 修复:想取"第 3 个"写 fruits[2];想取最后一个,无脑用 fruits[-1]——负数从队尾倒数,永远不会越界。举一反三:见到 IndexError,先 print(len(列表)) 数一数,再看下标是不是超了。

翻车二:把 append 的返回值装回列表

fruits = ["苹果"]
fruits = fruits.append("香蕉")
print(fruits)
None

逐行分析:第 1 行没问题;第 2 行是事故现场,坑在开头的 fruits =——后半句其实已经把"香蕉"装进列表了,append 干完活顺手返回一个 None(意思是"我没有返回值"),而你用 fruits = 把这个 None 覆盖装回了盒子,列表从此"失联"。Python 为什么不报错?赋值本来就是合法操作,它猜不到你是想保留列表——又一个"不报错却坏事"的逻辑 bug,直到第 3 行 print 把 None 亮出来才露馅。 修复:删掉 fruits =,单写一行 fruits.append("香蕉")。举一反三:列表的 append、sort、reverse 都是"原地动手、不还东西"的脾气,一律别拿它们的返回值去赋值。

翻车三:查了字典里没有的键

frog = {"名字": "小绿"}
print(frog["体重"])
KeyError: '体重'

逐行分析:第 2 行想按"体重"这个键取值,可字典里只登记过"名字",Python 沿着键找了一圈没找到,报 KeyError: '体重'——冒号后面就是那个找不到的键,指名道姓。注意:语法完全合法,Python 无法提前知道你会查什么键,所以它是运行到这一行才发现的。 修复两选一:确定键存在再查;拿不准就先用 if "体重" in frog: 探一句,或者用 frog.get("体重")——查不到时返回 None 而不是报错(先记个名字,以后常用)。

📦 完整小示例

用字典记三门课成绩,顺手算总分和平均分,存成 scores.py:

scores = {"语文": 92, "数学": 87, "英语": 95}
total = 0

for subject, score in scores.items():
    print(f"{subject}:{score} 分")
    total += score

print(f"总分:{total}")
print(f"平均分:{total / len(scores)}")

你会看到:

语文:92 分
数学:87 分
英语:95 分
总分:274
平均分:91.33333333333333

逐段中文精讲

  • 第 1 行(数据登记):字典把"科目 → 分数"一一配对登记。用字典而不是列表,是因为取数时你想按名字拿("数学多少分"),而不是按位置猜("第 2 个是什么")。
  • 第 2 行(累加器清零):total = 0 放循环外,理由和上一章的计数器一样:只需要归零一次,写进循环里每轮都被清空。
  • 第 3 行(空行)与第 4 行(遍历字典):登记完数据空一行再开工;scores.items() 把字典拆成一对对 (键, 值),for subject, score in ... 每轮同时接过一个键和一个值——这是字典遍历的标准姿势,一次拿两个。
  • 第 5~6 行(边遍历边干活):先打印本科目成绩(f-string 填坑),再 total += score 往存钱罐里加一笔,三科的分数就这样被"顺路"加总了。
  • 第 8 行(总分落袋):写在循环外,此刻三笔已加完,274 分出账。
  • 第 9 行(平均分):total / len(scores)——len() 数字典里有几个键(3 个),总分除以科数得平均。打印出的 91.33333333333333 拖着长尾巴,就是变量那章 Q4 说的浮点精度现象,学了格式化输出再收拾它。

这个例子是"字典 + 遍历 + 累加器"的经典组合:真实项目里统计订单总额、汇总考试得分,骨架就是这样。

🎯 什么时候用它

  • 购物车与清单:商品列表、待办事项、播放队列——有顺序、会增删的数据,天然是列表的主场:append 加货、del 移除、切片取一段。
  • 描述一个对象的属性:用户资料(姓名/城市/头像地址)、一件商品的详情、一份配置——"按名字取信息"的数据,用字典最顺手。
  • 读懂真实世界的数据:网页接口、小程序后端返回的数据(JSON),拆开看全是"列表套字典、字典套列表"——学透这两位,你就看懂了互联网数据的样子。

动手改

  1. 建一个列表装 5 个你喜欢的数字,打印最大值和最小值(提示:max() 和 min())
  2. 建一个字典存朋友的姓名、城市、爱好,新增一个键、再删掉一个键,每一步打印整个字典看变化
  3. 对列表 [3, 1, 4, 1, 5] 用切片取出第 2 到第 4 个数,并打印它的长度

下一章:函数,把代码打包成随叫随到的工具 🐸

📥 下载本章代码

ZIP 内含本章全部代码文件与说明,解压即用,与教程内容同步生成。