python中检查字典中键的正确方法
所以我一直在想。假设d是一本字典……检查字典中是否有键的正确(更像Python)方法是什么:python中检查字典中键的正确方法,python,dictionary,Python,Dictionary,所以我一直在想。假设d是一本字典……检查字典中是否有键的正确(更像Python)方法是什么: k in d or k in d.keys() 或者别的什么???总是使用 k in d 这是一个O(1)恒定时间操作 另一种选择是d.keys()中的k,在Python2中是一个O(N)线性时间操作,在Python3中充其量是一个不必要的方法调用。不要用它 d.keys()是三个额外的步骤,一个属性查找、一个函数调用和一个新对象的创建。在Python2中,它是所有键的列表对象(需要首先列出这些
k in d
or
k in d.keys()
或者别的什么???总是使用
k in d
这是一个O(1)恒定时间操作
另一种选择是d.keys()中的k
,在Python2中是一个O(N)线性时间操作,在Python3中充其量是一个不必要的方法调用。不要用它
d.keys()
是三个额外的步骤,一个属性查找、一个函数调用和一个新对象的创建。在Python2中,它是所有键的列表对象(需要首先列出这些键),在Python3中,它是字典视图。仅在测试是否存在密钥时,这两者都是完全冗余的。在Python2中,针对list对象的包容测试需要扫描所有元素,直到找到匹配项。k in d
无疑是最好的继续测试方法,因为它将更快O(1),因为它将使用字典的哈希,而不是线性搜索,在这种情况下,当您调用keys时就可以了
还有一种方法可以使用
dict.has_key(key)
。虽然Python3.0中不推荐使用“has_key”d中的k是有效的。当您执行d.keys()时,您将获得所有键作为列表,然后在列表中进行检查。因此,它必须先形成一个列表,根据列表的大小,性能会变慢。有更好的方法来检查所用的时间,但这应该有助于您看到差异:
d={}
for i in range(1000000):
d[i]=i*2
start_time = time.time()
if 2 in d:
print "yes"
print("-key in d -- %s seconds ---" % (time.time() - start_time))
start_time = time.time()
if 2 in d.keys():
print "yes"
print("--key in d.keys()- %s seconds ---" % (time.time() - start_time))
我的电脑上的输出:
yes
-key in d -- 0.0 seconds ---
yes
--key in d.keys()- 0.0169999599457 seconds ---
出于好奇,我刚刚在Python3中试用了它,实际上,与Python2相比,这两种操作现在看起来都像是O(1)操作
import random
import string
def rand_string(length):
""" Generates a random string of numbers, lower- and uppercase chars. """
return ''.join(random.choice(
string.ascii_lowercase + string.ascii_uppercase + string.digits)
for i in range(length)
)
big_dict = {rand_string(20):rand_string(20) for i in range(10000)}
比较 对于记录,使用try/except进行比较(感谢
timeit
模块)
代码
结果
以下是不同dict长度和是否输入dict的一些计时结果(以秒为单位):
简短的格言:
lend = 200
idx = 0
>> 0.18031001091 # k in d
>> 0.216886997223 # try/except
>> 1.06729197502 # k in d.keys()
lend = 200
idx = 201
>> 0.178912878036 # k in d
>> 1.32136297226 # try/except
>> 4.93310189247 # k in d.keys()
简而言之:
lend = 200
idx = 0
>> 0.18031001091 # k in d
>> 0.216886997223 # try/except
>> 1.06729197502 # k in d.keys()
lend = 200
idx = 201
>> 0.178912878036 # k in d
>> 1.32136297226 # try/except
>> 4.93310189247 # k in d.keys()
长篇格言:
lend = 20000
idx = 1
>> 0.178980827332 # k in d
>> 0.22277712822 # try/except
>> 105.207716942 # k in d.keys()
出自长篇大论:
lend = 20000
idx = 20001
>> 0.184767007828 # k in d
>> 1.38200902939 # try/except
>> 490.606647968 # k in d.keys()
结论
当键在dict中时,try/except方法比d中的k慢一点。但是,如果键不在dict中,try/except的性能较差,但优于d.keys()中的k
鉴于性能和可读性,k in d
是首选。任何一个都可以。我通常是第一个。@Cyber:不,在Python 2中不是。d中的k
是一种解决方法,您可以直接使用d[k]并捕获异常(如果缺少键很少见)或d.get(k,默认值),以防不存在。那么你就不需要做检查了。d.get(k)
的问题是当d[k]=None时,那么k在d!=(d.get(k)不是None)
dict.has_key()
已被弃用。它需要一个属性查找和一个函数调用(2条指令),而在@MartijnPieters中使用进行成员资格测试则需要一条字节码指令:-是的,我已经更新了!它在Python 2中被弃用,在Python 3中被完全删除。@MartijnPieters:-真的@帕德雷坎宁厄姆:-更新了。谢谢你的建议。如果你想使用时间代码,请使用timeit