字典(Dictionary)#
字典(Dictionary)儲存 鍵值對(key-value pair) ,透過 鍵(key) 快速查找對應的 值(value) :
1
2
3
4
5
6
7
8
9
10
11
12
13
| # 建立字典
person = {
"name": "Alice",
"age": 25,
"city": "Taipei"
}
# 空字典
empty = {}
empty2 = dict()
# 用 dict() 建立
profile = dict(name="Bob", age=30)
|
字典的特性:
- 有序 (Python 3.7+ 保留插入順序)
- 鍵不重複 (重複的鍵會覆蓋前一個值)
- 鍵必須可雜湊 (字串、數字、元組可以;串列不行)
存取元素#
1
2
3
4
5
6
7
8
9
10
11
12
| person = {"name": "Alice", "age": 25, "city": "Taipei"}
# 用鍵存取值
print(person["name"]) # Alice
print(person["age"]) # 25
# 鍵不存在時會報 KeyError
# print(person["email"]) # ❌ KeyError
# 用 get():鍵不存在時回傳 None 或預設值
print(person.get("email")) # None
print(person.get("email", "無")) # 無
|
修改字典#
新增與修改#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| person = {"name": "Alice", "age": 25}
# 修改既有的值
person["age"] = 26
print(person) # {'name': 'Alice', 'age': 26}
# 新增鍵值對
person["city"] = "Taipei"
print(person) # {'name': 'Alice', 'age': 26, 'city': 'Taipei'}
# update():批次更新
person.update({"age": 27, "email": "alice@example.com"})
print(person)
# {'name': 'Alice', 'age': 27, 'city': 'Taipei', 'email': 'alice@example.com'}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| person = {"name": "Alice", "age": 25, "city": "Taipei"}
# pop():刪除並回傳值
age = person.pop("age")
print(age) # 25
print(person) # {'name': 'Alice', 'city': 'Taipei'}
# pop() 可指定預設值,避免 KeyError
result = person.pop("email", "不存在")
print(result) # 不存在
# del:直接刪除
del person["city"]
print(person) # {'name': 'Alice'}
# clear():清空字典
person.clear()
print(person) # {}
|
遍歷字典#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| scores = {"Alice": 85, "Bob": 92, "Charlie": 78}
# 遍歷鍵
for name in scores:
print(name)
# 遍歷值
for score in scores.values():
print(score)
# 同時遍歷鍵和值(最常用)
for name, score in scores.items():
print(f"{name}:{score} 分")
# 遍歷鍵(明確寫法)
for name in scores.keys():
print(name)
|
查詢操作#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| person = {"name": "Alice", "age": 25, "city": "Taipei"}
# 是否存在(預設判斷鍵)
print("name" in person) # True
print("email" in person) # False
# 是否存在於值
print(25 in person.values()) # True
# 取得所有鍵、值、鍵值對
print(list(person.keys())) # ['name', 'age', 'city']
print(list(person.values())) # ['Alice', 25, 'Taipei']
print(list(person.items())) # [('name', 'Alice'), ('age', 25), ('city', 'Taipei')]
# 長度
print(len(person)) # 3
|
setdefault() 與 defaultdict#
setdefault():不存在時設定預設值#
1
2
3
4
5
6
7
8
9
10
| person = {"name": "Alice"}
# 鍵不存在時設定,並回傳值
email = person.setdefault("email", "unknown@example.com")
print(email) # unknown@example.com
print(person) # {'name': 'Alice', 'email': 'unknown@example.com'}
# 鍵已存在時不覆蓋
person.setdefault("name", "Bob")
print(person["name"]) # Alice(未被覆蓋)
|
計數模式#
1
2
3
4
5
6
7
8
| text = "hello world hello python world hello"
word_count = {}
for word in text.split():
word_count[word] = word_count.get(word, 0) + 1
print(word_count)
# {'hello': 3, 'world': 2, 'python': 1}
|
字典推導式#
字典推導式(Dict Comprehension)語法與串列推導式類似,差別在於用大括號,且要同時指定鍵和值,中間用冒號 : 分隔:
{鍵運算式: 值運算式 for 變數 in 可迭代物件}
{鍵運算式: 值運算式 for 變數 in 可迭代物件 if 條件}
基本形式:從序列建立字典#
傳統寫法:
1
2
3
4
| squares = {}
for x in range(1, 6):
squares[x] = x ** 2
print(squares) # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
|
用字典推導式改寫:
1
2
| squares = {x: x ** 2 for x in range(1, 6)}
print(squares) # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
|
加入條件:只保留符合條件的項目#
1
2
3
4
5
6
7
8
| # 只保留偶數的平方
even_squares = {x: x ** 2 for x in range(1, 11) if x % 2 == 0}
print(even_squares) # {2: 4, 4: 16, 6: 36, 8: 64, 10: 100}
# 過濾掉分數不及格的學生
scores = {"Alice": 85, "Bob": 55, "Charlie": 92, "David": 48}
passed = {name: score for name, score in scores.items() if score >= 60}
print(passed) # {'Alice': 85, 'Charlie': 92}
|
兩個串列合併成字典#
配合 zip() 把名稱串列和數值串列對應成字典:
1
2
3
4
5
| names = ["Alice", "Bob", "Charlie"]
scores = [85, 92, 78]
score_map = {name: score for name, score in zip(names, scores)}
print(score_map) # {'Alice': 85, 'Bob': 92, 'Charlie': 78}
|
轉換現有字典的值#
對字典的每個值做運算,鍵保持不變:
1
2
3
4
5
| prices = {"apple": 30, "banana": 15, "cherry": 25}
# 所有價格打八折
discounted = {item: price * 0.8 for item, price in prices.items()}
print(discounted) # {'apple': 24.0, 'banana': 12.0, 'cherry': 20.0}
|
反轉字典(鍵值互換)#
1
2
3
| original = {"a": 1, "b": 2, "c": 3}
reversed_dict = {v: k for k, v in original.items()}
print(reversed_dict) # {1: 'a', 2: 'b', 3: 'c'}
|
⚠️ 反轉時,原始字典的值必須是可雜湊(hashable)的型別(如整數、字串)才能當新鍵;若值有重複,後面的鍵會覆蓋前面的。
巢狀字典#
字典的值可以是另一個字典:
1
2
3
4
5
6
7
8
9
10
11
12
| students = {
"Alice": {"age": 20, "score": 85, "city": "Taipei"},
"Bob": {"age": 22, "score": 92, "city": "Kaohsiung"},
"Charlie": {"age": 21, "score": 78, "city": "Taichung"},
}
# 存取巢狀值
print(students["Alice"]["score"]) # 85
# 遍歷
for name, info in students.items():
print(f"{name}({info['city']}):{info['score']} 分")
|
合併字典(Python 3.9+)#
1
2
3
4
5
6
7
8
9
10
11
12
| defaults = {"color": "blue", "size": "M", "quantity": 1}
custom = {"color": "red", "quantity": 5}
# 合併(custom 的值覆蓋 defaults)
merged = defaults | custom
print(merged)
# {'color': 'red', 'size': 'M', 'quantity': 5}
# 原地更新
defaults |= custom
print(defaults)
# {'color': 'red', 'size': 'M', 'quantity': 5}
|
實戰範例#
統計選票#
1
2
3
4
5
6
7
8
9
10
| votes = ["Alice", "Bob", "Alice", "Charlie", "Bob", "Alice", "Bob"]
tally = {}
for vote in votes:
tally[vote] = tally.get(vote, 0) + 1
winner = max(tally, key=tally.get)
print(f"得票統計:{tally}")
print(f"勝選者:{winner}")
# 得票統計:{'Alice': 3, 'Bob': 3, 'Charlie': 1}
|
分組資料#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| students = [
{"name": "Alice", "city": "Taipei"},
{"name": "Bob", "city": "Kaohsiung"},
{"name": "Charlie", "city": "Taipei"},
{"name": "David", "city": "Kaohsiung"},
]
by_city = {}
for s in students:
city = s["city"]
by_city.setdefault(city, []).append(s["name"])
for city, names in by_city.items():
print(f"{city}:{', '.join(names)}")
# Taipei:Alice, Charlie
# Kaohsiung:Bob, David
|