繁体   English   中英

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

[英]Check if a given key already exists in a dictionary

我想在更新键的值之前测试一个键是否存在于字典中。 我写了以下代码:

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

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

in测试dict中是否存在键:

d = {"key1": 10, "key2": 23}

if "key1" in d:
    print("this will execute")

if "nonexistent key" in d:
    print("this will not")

当键不存在时,使用dict.get()提供默认值:

d = {}

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

要为每个键提供默认值,请在每个分配上使用dict.setdefault()

d = {}

for i in range(10):
    d[i] = d.setdefault(i, 0) + 1

或使用collections模块中的defaultdict

from collections import defaultdict

d = defaultdict(int)

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

您不必调用密钥:

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

这会快得多,因为它使用字典的散列而不是进行线性搜索,调用键会这样做。

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

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

在改变它之前检查字典中键是否存在的一个常见用途是默认初始化值(例如,如果您的值是列表,并且您希望确保有一个可以附加的空列表插入键的第一个值时)。 在这种情况下,您可能会发现collections.defaultdict()类型很有趣。

在旧代码中,您可能还会发现has_key()的一些用途,这是一种已弃用的检查字典中键是否存在的方法(只需key_name in dict_name )。

您可以将代码缩短为:

if 'key1' in my_dict:
    ...

然而,这充其量只是外观上的改进。 为什么你认为这不是最好的方法?

有关已接受答案的建议方法(1000 万次循环)的速度执行的更多信息:

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

因此,建议对get使用indefaultdict

我建议改用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}

Python 中的字典有一个get('key', default)方法。 所以你可以设置一个默认值,以防没有任何键。

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

使用Python 三元运算符

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

使用 EAFP(请求宽恕比请求许可更容易):

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

查看其他堆栈溢出帖子:

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

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

以下是方法:

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

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()更可靠,而且甚至更快。

获得结果的方法有:

哪个更好取决于三件事:

  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."

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

您可以使用has_key()方法:

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

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

d = defaultdict(int)

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

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.

另一种使用布尔运算符检查键是否存在的方法:

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'
>>>

您可以使用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')

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM