Python 3 中 dict.keys()、values()、items() 回傳視圖對象(dict_keys、dict_values、dict_items),而非 Python 2 的列表。視圖具備動態性(字典變更即時反映)、集合運算支援,但不支援索引存取。本文說明轉換方法、常見陷阱與跨版本相容寫法。
# Python 2
>>> d = {'a': 1, 'b': 2}
>>> d.keys()
['a', 'b'] # list
>>> d.keys()[0]
'a'
# Python 3
>>> d = {'a': 1, 'b': 2}
>>> d.keys()
dict_keys(['a', 'b']) # view object
>>> d.keys()[0]
TypeError: 'dict_keys' object does not support indexing
# 1. list() 強制轉列表(最常用) keys_list = list(d.keys()) print(keys_list[0]) # 'a' # 2. 解包語法(Python 3.5+) *keys_list, = d.keys() # 3. 列表推導式 keys_list = [k for k in d.keys()] # 4. 直接 list(d) 等同 list(d.keys()) keys_list = list(d)
keys()。& (交集)、| (聯集)、- (差集)、^ (對稱差集)。
d1 = {'a':1, 'b':2, 'c':3}
d2 = {'b':2, 'c':3, 'd':4}
print(d1.keys() & d2.keys()) # {'b', 'c'}
print(d1.keys() | d2.keys()) # {'a', 'b', 'c', 'd'}
for k in d.keys(): 直接可用,無需轉列表。# Python 3 >>> zip(d.keys(), d.values())>>> list(zip(d.keys(), d.values())) [('a', 1), ('b', 2)]
需額外 list() 實體化。
# 方式 1:六庫(six)兼容層
from six import iterkeys, itervalues, iteritems
for k in iterkeys(d): ...
# 方式 2:try/except 判斷
try:
# Python 2
keys_list = d.keys()
except AttributeError:
# Python 3
keys_list = list(d.keys())
# 方式 3:統一用 list(),Python 2 list(list) 無副作用
keys_list = list(d.keys()) # 兩版本皆正確,Python 2 只是多一次複製
# 依值排序取鍵 sorted_keys = sorted(d, key=d.get) # Python 2/3 通用 # 或 sorted_keys = sorted(d.keys(), key=d.get) # 明確語義 # 依鍵排序 sorted_keys = sorted(d.keys())
總結:Python 3 視圖物件設計更現代、高效。日常迭代、集合運算直接用視圖;需索引、序列化、傳遞給要求列表的 API 時,再 list(d.keys()) 實體化。跨版本專案統一用 list(d.keys()) 最省心。