HOWTO · Python
如何在 Python 中將字典的鍵轉成列表
了解如何用 list()、迴圈、列表推導式或解包語法取得 Python 字典的鍵列表,並分辨 dict_keys 檢視物件與列表。
本頁內容
若要將 Python 字典的鍵 轉成列表,直接使用 list(my_dict);list(my_dict.keys()) 也會得到相同結果。這兩種寫法都透過 list() 建構子建立新的鍵列表。單獨呼叫 my_dict.keys() 會得到 dict_keys 檢視物件;它可以迭代,卻不能像列表一樣用索引取值。需要列表物件時再轉換;如果只要逐一處理鍵,通常直接迭代字典就夠了。
dict.keys() 取得 Python 字典的鍵
dict.keys() 方法會傳回目前字典鍵的檢視物件。之後若修改字典,檢視物件會反映變更;由它建立的列表則是獨立的資料快照。在 Python 3.7 及更新版本中,迭代字典會依鍵的插入順序進行;以下輸出採用這項順序保證。
state_capitals = {
"California": "Sacramento",
"Pennsylvania": "Harrisburg",
"Texas": "Austin",
}
keys_view = state_capitals.keys()
print(keys_view)
for state in keys_view:
print(state)
keys_list = list(keys_view)
print(keys_list)
print(list(state_capitals))
print(keys_list[0])
state_capitals["Nevada"] = "Carson City"
print(list(keys_view))
print(keys_list)
dict_keys(['California', 'Pennsylvania', 'Texas'])
California
Pennsylvania
Texas
['California', 'Pennsylvania', 'Texas']
['California', 'Pennsylvania', 'Texas']
California
['California', 'Pennsylvania', 'Texas', 'Nevada']
['California', 'Pennsylvania', 'Texas']
list(keys_view) 與 list(state_capitals) 都會建立列表。後者之所以可行,是因為迭代字典會取得鍵。若直接對檢視物件使用索引,會引發 TypeError。空字典轉成列表會得到 [];若再對這個空列表取索引,則會引發 IndexError。
使用迴圈取得 Python 字典的鍵
如果收集鍵時還需要逐一處理,可以明確寫出迴圈。使用 for key in state_capitals:其中的 in 是必要的關鍵字,迴圈取得的是鍵,而不是值。
state_capitals = {
"California": "Sacramento",
"Pennsylvania": "Harrisburg",
"Texas": "Austin",
}
keys = []
for key in state_capitals:
keys.append(key)
print(keys)
['California', 'Pennsylvania', 'Texas']
若字典為空,迴圈不會執行,keys 會維持空列表。如果只是單純取得鍵,沒有其他逐項處理,list(state_capitals) 更簡潔。
使用列表推導式取得 Python 字典的鍵
列表推導式 能以一行寫出相同的收集迴圈。若要加上篩選條件或轉換每個鍵,這種寫法很適合;若只要複製鍵,使用 list() 建構子更簡單。
state_capitals = {
"California": "Sacramento",
"Pennsylvania": "Harrisburg",
"Texas": "Austin",
}
keys = [key for key in state_capitals]
print(keys)
['California', 'Pennsylvania', 'Texas']
字典為空時,這個列表推導式也會得到 []。
使用 Python 字典解包運算子 * 取得鍵
可迭代物件的解包語法 * 能將字典的鍵放進列表:[*state_capitals]。PEP 448 在 Python 3.5 擴充了解包語法;這項版本相容性來自語法規範,並非在此以 Python 3.5 實際執行驗證。元組和集合也能使用解包語法。
state_capitals = {
"California": "Sacramento",
"Pennsylvania": "Harrisburg",
"Texas": "Austin",
}
keys_list = [*state_capitals]
keys_tuple = (*state_capitals,)
keys_set = {*state_capitals}
print(keys_list)
print(keys_tuple)
print(sorted(keys_set))
['California', 'Pennsylvania', 'Texas']
('California', 'Pennsylvania', 'Texas')
['California', 'Pennsylvania', 'Texas']
集合會去除重複元素,而且不保證顯示順序;範例使用 sorted(),讓輸出內容的順序可預期。在 Python 3.7 及更新版本中,元組和列表會保留字典的迭代順序。如果結果必須是列表,就使用列表寫法。
比較各種方法的執行效能
如果轉換速度很重要,請用實際使用的 Python 直譯器,以及與真實資料規模相近的字典測量。以下程式會印出 Python 版本,並對同一個含 100 筆資料的字典,各執行五輪、每輪轉換 10,000 次,再回報其中最快一輪的平均單次時間。每次計時的運算都會建立新列表;迴圈寫法每次轉換也會重新建立用來存放結果的列表。
import platform
from timeit import repeat
state_capitals = {str(number): number for number in range(100)}
methods = {
"list(d.keys())": "list(state_capitals.keys())",
"list(d)": "list(state_capitals)",
"loop": "keys = []\nfor key in state_capitals:\n keys.append(key)",
"comprehension": "[key for key in state_capitals]",
"unpacking": "[*state_capitals]",
}
print("Python", platform.python_version())
for name, statement in methods.items():
times = repeat(statement, globals=globals(), number=10_000, repeat=5)
print(f"{name}: {min(times) / 10_000:.9f} seconds per conversion")
印出的時間會受直譯器、電腦及字典大小影響,因此沒有固定輸出,也沒有在所有環境都最快的方法。一般程式碼可優先選用易讀的 list(state_capitals);只有當轉換成本對程式有明顯影響時,才需要比較其他寫法。