检查字典中是否已存在给定键

我想在更新密钥值之前测试字典中是否存在密钥。 我写了以下代码:

if 'key1' in dict.keys():
  print "blah"
else:
  print "boo"

我认为这不是完成此任务的最佳方法。 有没有更好的方法来测试字典中的键?


#1楼

您不必呼叫按键:

if 'key1' in dict:
  print "blah"
else:
  print "boo"

这将更快,因为它使用字典的哈希而不是进行线性搜索(调用键可以做到)。


#2楼

您可以缩短此时间:

if 'key1' in dict:
    ...

但是,这充其量是对化妆品的改善。 为什么您认为这不是最好的方法?


#3楼

我建议改用setdefault方法。 听起来它将满足您的所有要求。

>>> d = {'foo':'bar'}
>>> q = d.setdefault('foo','baz') #Do not override the existing key
>>> print q #The value takes what was originally in the dictionary
bar
>>> print d
{'foo': 'bar'}
>>> r = d.setdefault('baz',18) #baz was never in the dictionary
>>> print r #Now r has the value supplied above
18
>>> print d #The dictionary's been updated
{'foo': 'bar', 'baz': 18}

#4楼

in是测试dict密钥是否存在的预期方法。

d = dict()

for i in range(100):
    key = i % 10
    if key in d:
        d[key] += 1
    else:
        d[key] = 1

如果要使用默认值,则可以始终使用dict.get()

d = dict()

for i in range(100):
    key = i % 10
    d[key] = d.get(key, 0) + 1

...,如果您想始终确保任何键的默认值,则可以从collections模块中使用defaultdict ,如下所示:

from collections import defaultdict

d = defaultdict(int)

for i in range(100):
    d[i % 10] += 1

...但总的来说, in关键字是最好的方法。


#5楼

您可以使用in关键字测试字典中是否存在键:

d = {'a': 1, 'b': 2}
'a' in d # <== evaluates to True
'c' in d # <== evaluates to False

在更改字典之前,在字典中检查键是否存在的常见用途是对值进行默认初始化(例如,如果您的值是列表,并且您想确保可以在其后附加一个空列表)在插入键的第一个值时)。 在这种情况下,您可能会发现collections.defaultdict()类型令人感兴趣。

在较早的代码中,您可能还会发现has_key()一些用法, has_key()是一种不推荐使用的方法,用于检查字典中键的存在(仅key_name in dict_name使用key_name in dict_name )。


#6楼

仅限in Python 2 :(并且python 2.7已支持)

您可以使用has_key()方法:

if dict.has_key('xyz')==1:
    #update the value for the key
else:
    pass

#7楼

只是克里斯的补充。 B(最佳答案):

d = defaultdict(int)

也可以; 原因是调用int()返回0 ,这是defaultdict在后台(构造字典时)所做的事情,因此在文档中名称为“ Factory Function”。


#8楼

如何使用EAFP(比请求更容易获得宽恕):

try:
   blah = dict["mykey"]
   # key exists in dict
except KeyError:
   # key doesn't exist in dict

查看其他SO帖子:

在python中使用try vs if

在Python中检查成员是否存在


#9楼

有关接受的答案的建议方法(10m循环)的快速执行的其他信息:

  • 'key' in mydict经过时间1.07秒
  • mydict.get('key')经过的时间1.84秒
  • mydefaultdict['key']经过的时间1.07秒

因此in建议使用indefaultdict反对get


#10楼

获得结果的方式是:

哪个更好取决于三个因素:

  1. 字典“通常没有钥匙”还是“通常没有钥匙”。
  2. 您是否打算使用if ... else ... elseif ... else之类的条件?
  3. 字典有多大?

了解更多: http : //paltman.com/try-except-performance-in-python-a-simple-test/

使用try / block代替“ in”或“ if”:

try:
    my_dict_of_items[key_i_want_to_check]
except KeyError:
    # Do the operation you wanted to do for "key not present in dict".
else:
    # Do the operation you wanted to do with "key present in dict."

#11楼

python中的Dictionary具有get('key',default)方法。 因此,您可以在没有密钥的情况下设置默认值。

values = {...}
myValue = values.get('Key', None)

#12楼

Python字典具有称为__contains__的方法。 如果字典具有键,则此方法将返回True,否则返回False。

 >>> temp = {}

 >>> help(temp.__contains__)

Help on built-in function __contains__:

__contains__(key, /) method of builtins.dict instance
    True if D has a key k, else False.

#13楼

使用三元运算符:

message = "blah" if 'key1' in dict else "booh"
print(message)

#14楼

您可以使用for循环遍历字典并获取要在字典中找到的键的名称,然后检查是否存在或不使用if条件:

dic = {'first' : 12, 'second' : 123}
for each in dic:
    if each == 'second': 
        print('the key exists and the corresponding value can be updated in the dictionary')

#15楼

共享使用布尔运算符检查密钥是否存在的另一种方法。

d = {'a': 1, 'b':2}
keys = 'abcd'

for k in keys:
    x = (k in d and 'blah') or 'boo'
    print(x) 

这返回

>>> blah
>>> blah
>>> boo
>>> boo

说明

首先,您应该知道在Python中, 0None或长度为零的对象的值为False 。 其他所有结果都为True 。 布尔运算从左到右求值,并且返回的操作数不是True或False。

让我们来看一个例子:

>>> 'Some string' or 1/0 
'Some string'
>>>

由于'Some string'计算结果为True ,其余的or不计算,并且不存在除以零的错误。

但是,如果我们切换顺序1/0则会首先对其求值并引发异常:

>>> 1/0 or 'Some string'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
>>> 

我们可以使用此模式检查密钥是否存在。

(k in d and 'blah')

与...相同

if k in d:
    'blah'
else:
    False

如果键存在,这已经返回了正确的结果,但是我们希望它在不存在时打印“ boo”。 所以,我们采取的结果, or将其与'boo'

>>> False or 'boo'
'boo'
>>> 'blah' or 'boo'
'blah'
>>> 

#16楼

检查字典中是否已存在给定键

为了了解如何做到这一点,我们首先检查可以在字典上调用的方法。 方法如下:

d={'clear':0, 'copy':1, 'fromkeys':2, 'get':3, 'items':4, 'keys':5, 'pop':6, 'popitem':7, 'setdefault':8, 'update':9, 'values':10}

Python Dictionary clear()       Removes all Items
Python Dictionary copy()        Returns Shallow Copy of a Dictionary
Python Dictionary fromkeys()    Creates dictionary from given sequence
Python Dictionary get()         Returns Value of The Key
Python Dictionary items()       Returns view of dictionary (key, value) pair
Python Dictionary keys()        Returns View Object of All Keys
Python Dictionary pop()         Removes and returns element having given key
Python Dictionary popitem()     Returns & Removes Element From Dictionary
Python Dictionary setdefault()  Inserts Key With a Value if Key is not Present
Python Dictionary update()      Updates the Dictionary 
Python Dictionary values()      Returns view of all values in dictionary

检查密钥是否已存在的残酷方法可能是get()方法:

d.get("key")

其他两个有趣的方法items()keys()听起来工作量太大。 因此,让我们检查一下get()是否适合我们。 我们有dict d

d= {'clear':0, 'copy':1, 'fromkeys':2, 'get':3, 'items':4, 'keys':5, 'pop':6, 'popitem':7, 'setdefault':8, 'update':9, 'values':10}

打印显示我们没有的键将返回None

print(d.get('key')) #None
print(d.get('clear')) #0
print(d.get('copy')) #1

如果密钥存在或不存在,我们 可能会 用它来获取信息。 但是如果我们用一个key:None创建一个字典,请考虑一下key:None

d= {'key':None}
print(d.get('key')) #None
print(d.get('key2')) #None

如果某些值可能为None则导致get()方法不可靠。 这个故事的结局应该更快乐。 如果我们使用in比较器:

print('key' in d) #True
print('key2' in d) #False

我们得到正确的结果。 我们可以检查一下Python字节码:

import dis
dis.dis("'key' in d")
#   1           0 LOAD_CONST               0 ('key')
#               2 LOAD_NAME                0 (d)
#               4 COMPARE_OP               6 (in)
#               6 RETURN_VALUE

dis.dis("d.get('key2')")
#   1           0 LOAD_NAME                0 (d)
#               2 LOAD_METHOD              1 (get)
#               4 LOAD_CONST               0 ('key2')
#               6 CALL_METHOD              1
#               8 RETURN_VALUE

这表明in compare运算符中,它不仅比get()更加可靠,而且甚至更快。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值