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