dict.has_key(key) 是 Python 2 專有方法,Python 3 已移除。現代代碼請統一使用 key in dict 運算子。
# Python 2
d = {'Name': 'Zara', 'Age': 7}
print(d.has_key('Age')) # True
print(d.has_key('Sex')) # False
d = {'Name': 'Zara', 'Age': 7}
print('Age' in d) # True
print('Sex' in d) # False
| 特性 | key in d | d.has_key(key) (Py2) |
|---|---|---|
| 語法 | 運算子 | 方法呼叫 |
| 可讀性 | 高 (類英文) | 中 |
| 效能 | 相同 (皆為雜湊查找) | 相同 |
| 適用物件 | 所有支援 __contains__ (dict, set, list, str...) | 僅 dict |
| Python 3 支援 | 是 | 否 (AttributeError) |
import timeit
d = {str(i): i for i in range(10000)}
# in 運算子
t1 = timeit.timeit('"5000" in d', globals=globals(), number=100000)
# has_key (Py2 only,這裡模擬)
t2 = timeit.timeit('d.__contains__("5000")', globals=globals(), number=100000)
print(f'in: {t1:.3f}s')
print(f'__contains__: {t2:.3f}s')
# 差異可忽略
# 1. 直接替換
# d.has_key(k) -> k in d
# 2. 搭配 get 取值
# if d.has_key(k): v = d[k]
# -> v = d.get(k) (None 代表不存在)
# -> if k in d: v = d[k]
# 3. 批次檢查
# all(k in d for k in keys)
# any(k in d for k in keys)
def has_key(d, key):
"""跨版本 has_key"""
return key in d
# 或使用 six 庫
# from six import iteritems, iterkeys
# 六庫已停維護,建議直接用 in
# 集合
s = {1, 2, 3}
print(2 in s) # True
# 列表 (O(n) 線性搜尋)
lst = [1, 2, 3]
print(2 in lst) # True
# 字串 (子字串檢查)
print('ell' in 'hello') # True
# 自訂類別實作 __contains__
class MyContainer:
def __init__(self, data):
self.data = data
def __contains__(self, key):
return key in self.data
c = MyContainer({'a': 1})
print('a' in c) # True
結論:has_key() 是歷史遺物,現代 Python 統一使用 in 運算子,語法統一、適用面廣、效能相同。