上一课我们用列表一次存一堆数据。但列表有个痛点:它靠"下标"找数据。你想找"张三的成绩",得先知道张三排在第几个位置,或者一个个扫过去。

现实里我们更习惯这样:直接喊名字,就知道成绩

scores = {"张三": 90, "李四": 85, "王五": 78}
print(scores["张三"])      # 90,直接按名字拿

这就是这一课的主角——字典(dict)。它让你能"按键查值",而且快到离谱。


一、字典:键值对的仓库

字典用花括号 {},里面是一对一对的 键(key): 值(value)

person = {
    "name": "张三",
    "age": 20,
    "city": "北京"
}
print(person["name"])   # 张三
print(person["age"])    # 20
  • :就是"名字",用来查找。必须是不可变的(字符串、数字、元组可以;列表不行)。
  • :任何东西都可以,数字、字符串、列表、甚至另一个字典。

二、增删改查

d = {}

d["name"] = "张三"       # 增:直接赋值就是新增
d["age"] = 20

d["age"] = 21            # 改:键已存在,赋值就是覆盖

print(d["name"])         # 查:按键取值

del d["age"]             # 删:删除键值对

"name" in d              # 判断键是否存在(O(1) 快)
⚠️ 查一个不存在的键会报错 KeyError。想安全地查,用 d.get("key", 默认值)
print(d.get("age", "没有这个键"))   # 键不存在时返回默认值,不报错

三、遍历字典

d = {"a": 1, "b": 2, "c": 3}

for k in d:              # 遍历键
    print(k)

for v in d.values():     # 遍历值
    print(v)

for k, v in d.items():   # 同时遍历键和值
    print(k, v)

四、集合:自动去重 + 闪电判断

集合(set)可以理解成"没有值的字典",或者"不能有重复元素的列表"。用花括号 {}

s = {1, 2, 3, 3, 3}
print(s)                # {1, 2, 3}   重复的自动去掉了

s.add(4)                # 加一个
s.remove(2)             # 删一个
2 in s                  # 判断在不在,O(1) 闪电快
len(s)                  # 元素个数

集合最厉害的两件事:

  1. 去重:把一个列表丢进 set(),重复的瞬间没。
  2. 成员判断x in s 是 O(1),比列表的 x in list(O(n))快几百上千倍。
🧊 冷笑话:A 说"我脑子里有一堆重复的想法"。B 说"扔进 set() 里"。A 问"然后呢?"B 答"就只剩一个想法了——'我什么都没了'。"

五、集合运算:并、交、差

a = {1, 2, 3, 4}
b = {3, 4, 5, 6}

a | b     # 并集 {1, 2, 3, 4, 5, 6}
a & b     # 交集 {3, 4}
a - b     # 差集 {1, 2}(在 a 里、不在 b 里)
a ^ b     # 对称差 {1, 2, 5, 6}(只在一方的)

六、推导式:字典和集合也有

列表有推导式,字典和集合同样有:

# 字典推导式
squares = {x: x*x for x in range(1, 6)}
print(squares)          # {1:1, 2:4, 3:9, 4:16, 5:25}

# 集合推导式
evens = {x for x in range(1, 11) if x % 2 == 0}
print(evens)            # {2, 4, 6, 8, 10}

七、一个高频应用:统计词频

字典 + 集合的经典配合——统计一篇文章里每个词出现了几次:

text = "the cat and the dog and the bird"
words = text.split()

count = {}
for w in words:
    count[w] = count.get(w, 0) + 1   # 没见过记 1,见过就 +1

print(count)
# {'the': 3, 'cat': 1, 'and': 2, 'dog': 1, 'bird': 1}

这行 count.get(w, 0) + 1 是精髓:get 拿不到就返回 0,然后 +1,巧妙地完成了"计数"。


八、动手时间 🎯

实验 1:电话本

phone = {}
while True:
    name = input("输入名字(q 退出):")
    if name == "q":
        break
    if name in phone:
        print(f"{name} 的电话是 {phone[name]}")
    else:
        num = input("没有记录,输入电话存起来:")
        phone[name] = num

实验 2:列表去重,且保持顺序

nums = [3, 1, 2, 1, 3, 4, 2]
seen = set()
result = []
for x in nums:
    if x not in seen:
        seen.add(x)
        result.append(x)
print(result)   # [3, 1, 2, 4]

实验 3:找两个列表里都出现的元素

a = [1, 2, 3, 4, 5]
b = [4, 5, 6, 7, 8]
print(set(a) & set(b))   # {4, 5}

九、小结

  1. 字典是"按键查值"的仓库,键要不可变、值随便;get() 能安全查值不报错。
  2. 集合是"自动去重 + O(1) 判断"的利器in 快到离谱,还有并交差运算。
  3. 遇到"查找、去重、计数、判重",先想到字典和集合,能把 O(n) 砍成 O(1)。

下一课,我们学 函数——把一段代码打包、起个名字,随用随调。这是"复用代码"的开始,也是你从"会写几行"迈向"会写程序"的关键一步。

先把「电话本」和「词频统计」敲熟,字典和集合的手感就长在你脑子里了。

标签: none

添加新评论