Python 中九個常見字典與異常處理錯誤與解決方案
今天,我們將一起發現并解決在使用字典時遇到的15個常見陷阱,讓你的編程之旅更加順暢。
第一部分:字典基礎與常見錯誤
1. 創建字典的誤解
錯誤場景:嘗試用列表推導式創建字典時,鍵重復導致覆蓋。
# 錯誤示范
keys = ['a', 'b', 'a']
values = [1, 2, 3]
my_dict = {k: v for k, v in zip(keys, values)}
print(my_dict) # 輸出可能不是預期,因為'a'鍵被覆蓋了
解決方案:使用collections.defaultdict避免鍵沖突。
from collections import defaultdict
my_dict = defaultdict(list)
for k, v in zip(keys, values):
my_dict[k].append(v)
print(my_dict) # {'a': [1, 3], 'b': [2]}
2. 字典訪問未初始化鍵
錯誤場景:
my_dict = {}
value = my_dict['not_here'] # KeyError
解決方案:使用get方法安全訪問。
value = my_dict.get('not_here', '默認值')
print(value) # 輸出 '默認值'
3. 字典更新時的鍵沖突
錯誤理解:
dict1 = {'x': 1}
dict2 = {'x': 2, 'y': 3}
dict1.update(dict2)
# 預期dict1中'x'的值不變
正確做法:更新操作會覆蓋鍵值。
print(dict1) # {'x': 2, 'y': 3} 注意'x'的值已被覆蓋
異常處理入門
4. 不處理異常的危險
問題:運行時錯誤未被捕獲。
num = 'one'
result = num + 1 # TypeError
引入try-except:
try:
result = num + 1
except TypeError:
print("不能將字符串與數字相加")
5. 使用finally清理資源
無論是否發生異常,finally塊都會執行。
try:
# 假設這是打開文件的操作
file = open('example.txt', 'r')
print(file.read())
except FileNotFoundError:
print("文件不存在")
finally:
file.close() # 確保文件被關閉
第二部分:高級技巧與實戰案例
6. 字典推導式的高級用法
高級示例:創建一個映射,將字符串轉換為它們的長度。
words = ['apple', 'banana', 'cherry']
lengths = {word: len(word) for word in words}
print(lengths) # {'apple': 5, 'banana': 6, 'cherry': 6}
7. Python 3.5+:字典解構合并
新特性:利用解構簡化字典合并。
dict1 = {'x': 1, 'y': 2}
dict2 = {'y': 3, 'z': 4}
merged = {**dict1, **dict2} # Python 3.5+
print(merged) # {'x': 1, 'y': 3, 'z': 4}
8. 異常鏈:提供更詳細的錯誤信息
深入異常處理:
try:
raise ValueError("Something wrong!")
except ValueError as ve:
raise KeyError("This happened because of a value error.") from ve
這樣可以保留原始異常信息,增強調試能力。
9. 自定義異常
提升代碼質量:
class CustomError(Exception):
pass
try:
raise CustomError("這是一個自定義錯誤")
except CustomError as ce:
print(ce)
實戰案例:數據分析預處理
假設我們需要處理一份數據,其中包含一個字典列表,每個字典代表一條記錄,但數據不完全或有格式錯誤。我們的任務是清洗數據,處理缺失值,并捕獲任何轉換過程中的異常。
data = [
{"name": "Alice", "age": 30},
{"name": "Bob", "missed_age": 25}, # 錯誤鍵名
{"name": "Charlie"}, # 缺失年齡
]
cleaned_data = []
for record in data:
try:
# 確保記錄中有'age'鍵
age = record.get('age', None)
if age is None:
raise ValueError("Age is missing.")
# 正確處理記錄
cleaned_record = {
"name": record["name"],
"age": int(age), # 強制類型轉換,可能引發ValueError
}
cleaned_data.append(cleaned_record)
except KeyError as ke:
print(f"Key error in record: {ke}")
except ValueError as ve:
print(f"Value error in record: {ve}")
print(cleaned_data)
在這個實戰案例中,我們結合了字典操作和異常處理,展示了如何優雅地處理數據清洗過程中常見的問題。通過使用try-except結構,我們能夠捕獲并妥善處理異常,保證程序的健壯性。