HOWTO · Python
在 Python 字典中按值查詢鍵
本教程演示瞭如何在 Python 字典中按值獲取鍵。
本頁內容
Python 字典會將鍵對應至值,因此要從值尋找鍵,就必須搜尋字典中的項目。逐一走訪每組鍵值,並將其中的值與目標值比較。若只需要第一個符合的鍵,可使用迴圈或 next();若需要所有符合的鍵,則可使用列表推導式。這些搜尋會逐一檢查項目,直到找到符合項目或搜尋完整個字典為止。
使用迴圈搜尋鍵值組
dict.items() 會提供可迭代的鍵值組。使用迴圈走訪這些組合,即可回傳第一個值等於目標值的鍵。迴圈結束後回傳 None,能讓呼叫端清楚得知沒有符合項目;如果 None 本身也可能是有效的鍵,請改用不同的哨兵值,或回傳 (found, key) 配對。
執行以下範例:
本節中的程式碼以及顯示的標籤或輸出仍為英文。
def find_key_by_value(dictionary, target):
for key, value in dictionary.items():
if value == target:
return key
return None
scores = {"Ada": 91, "Lin": 87, "Sam": 91}
print(find_key_by_value(scores, 87))
Lin
找到符合項目時,迴圈會立即回傳,因此結果是依字典迭代順序遇到的第一個符合鍵。如果多個鍵具有目標值,找到第一個之後就不會再檢查後續項目。
使用 next() 取得第一個符合的鍵
產生器運算式可以精簡地表達相同的第一筆符合項目搜尋。將它傳入 next() 並提供預設值;如果產生器找不到符合的鍵,呼叫就會回傳 None,而不會引發 StopIteration。
將 target 設為函式的參數,讓範例可用符合或不符合的目標值呼叫:
本節中的程式碼以及顯示的標籤或輸出仍為英文。
def find_key_with_next(dictionary, target):
return next((key for key, value in dictionary.items() if value == target), None)
scores = {"Ada": 91, "Lin": 87, "Sam": 91}
print(find_key_with_next(scores, 87))
print(find_key_with_next(scores, 100))
產生器會在需要時才產生鍵,因此不會建立包含所有符合項目的列表。沒有值符合時會回傳預設值。如果資料中可能有 None 作為鍵,請選擇不會與有效鍵混淆的預設值。
使用推導式收集所有符合的鍵
若重複值也很重要,可使用列表推導式收集所有符合的鍵:
本節中的程式碼以及顯示的標籤或輸出仍為英文。
def find_all_keys(dictionary, target):
return [key for key, value in dictionary.items() if value == target]
scores = {"Ada": 91, "Lin": 87, "Sam": 91}
print(find_all_keys(scores, 91))
['Ada', 'Sam']
如果沒有任何值符合,回傳的列表會是空列表;否則會包含所有符合的鍵。也可以使用 filter() 運算式篩選符合的鍵值組,但列表推導式能在同一處清楚呈現條件與收集的鍵。
透過對齊的鍵和值列表尋找鍵
另一種做法是將 dict.keys() 和 dict.values() 轉換成列表。兩個列表的位置彼此對應:位置 i 的鍵對應到位置 i 的值。在值列表上呼叫 index(),可以找出目標值第一次出現的位置;再用該位置從鍵列表取出對應的鍵。
本節中的程式碼以及顯示的標籤或輸出仍為英文。
scores = {"Ada": 91, "Lin": 87, "Sam": 91}
keys = list(scores.keys())
values = list(scores.values())
position = values.index(91)
print(keys[position])
Ada
如果值不存在,index() 會引發 ValueError;若預期可能找不到值,請先檢查 values 是否包含該值,或處理這個錯誤。如果有重複值,index() 只會選取第一個符合的位置。
處理重複值、缺少的值與效能
請依任務選擇結果形式:迴圈或 next() 會回傳一個鍵,列表推導式則會回傳所有符合的鍵。第一筆符合項目的作法,以及 index(),都會在找到第一筆後停止;結果取決於字典的迭代順序。找不到值時,可以回傳 None 或空列表;對齊列表的作法則會引發 ValueError,除非先檢查值是否存在或處理該錯誤。
這些作法在最壞情況下都可能檢查每個項目,因此搜尋所需時間會隨字典項目數量成比例增加。迴圈和產生器運算式不會建立符合項目的集合。列表推導式會建立結果列表;對齊列表的作法則會在搜尋前分別建立鍵和值的列表。如果需要反覆依值查找鍵,可以考慮維護反向映射;但要留意重複值,因為簡單的反向字典每個值只會保留一個鍵。若要搜尋巢狀字典,請先決定要搜尋哪一層,再對該字典套用相同的逐項迭代方式。