简体   繁体   English

密钥检查中“key in dict”和“dict.get(key)”之间的区别

[英]Difference between "key in dict" and "dict.get(key)" on key check

When I was doing Leetcode 820 , building a Trie, there is a bug in my code.当我在做Leetcode 820 ,构建一个 Trie 时,我的代码中有一个错误。 I found it, also corrected it, but did NOT understand why.我找到了它,也更正了它,但不明白为什么。 Could anyone help?有人可以帮忙吗?

I made a simple test code here.我在这里做了一个简单的测试代码。 Program 1 and Program 2 are doing same thing, that is, given a word list words , it builds a Trie in reversed order of these words.程序 1 和程序 2 做同样的事情,即给定一个单词列表words ,它以这些单词的相反顺序构建一个 Trie。 Variable trie stored the root of Trie, variable leaves stored beginning character of each word.变量trie存储Trie 的根,变量leaves存储每个单词的开始字符。 The only difference between program 1 and program 2 is in line # difference , and I focus on the different results of leaves in 2 programs.程序 1 和程序 2 之间的唯一区别在于# difference ,我重点关注 2 程序中leaves的不同结果。

words = ["time", "atime", "btime"]

# program 1
trie = dict()
leaves = []
for word in words:
    node = trie
    for c in reversed(word):
        if c not in node:  # difference
            node[c] = dict()
        node = node[c]
    leaves.append(node)
print("from program 1: ")
print(leaves)

# program 2
trie = dict()
leaves = []
for word in words:
    node = trie
    for c in reversed(word):
        if not node.get(c):  # difference
            node[c] = dict()
        node = node[c]
    leaves.append(node)
print("from program 2: ")
print(leaves)

However the outputs of leaves are totally different.然而leaves的输出是完全不同的。

from program 1: 
[{'a': {}, 'b': {}}, {}, {}]
from program 2: 
[{}, {}, {}]

Could anyone help explain why results of leaves in program 1 and program 2 are different?谁能帮助解释为什么程序 1 和程序 2 中的leaves结果不同? Thanks so much in advance!提前非常感谢!

c not in node can only be True when node does not contain the key c . c not in node只有在node不包含键c时才能为 True。

Lots of things can make not node.get(c) return True.很多事情都可以使not node.get(c)返回 True。 Any falsy value, for example, like an empty list , dict or str , or something like 0 or 0.0 , evaluates to boolean False, just like None does.任何虚假值,例如空listdictstr或类似00.0的东西,评估为 boolean False,就像None一样。 So you are liable to get a false negative any time node contains c , but has a falsy value.因此,任何时候node包含c ,但具有虚假值时,您都有可能得到假阴性。

If you're absolutely sure that your mapping can not contain None values, you can do the following:如果您绝对确定您的映射不能包含 None 值,您可以执行以下操作:

if node.get(c) is not None:

If course explicitly checking for a key is always better than implicitly checking is by other means because of unintended side-effects like that.当然,如果显式检查一个键总是比通过其他方式隐式检查更好,因为这样会产生意想不到的副作用。

One obvious difference:一个明显的区别:

  • key in dict will only give you a false value if the key is not there.如果密钥不存在key in dict的 key 只会给你一个错误的值。
  • dict.get(key) will give you the actual value for that key which is then treated as a truthy or falsey value. dict.get(key)将为您提供该键的实际值,然后将其视为真值或假值。 So, if the value for an existing key is falsey (such as zero or the empty string), the if statement will not fire (though it will in the previous bullet point).因此,如果现有键的值是错误的(例如零或空字符串),则if语句将不会触发(尽管它会在上一个要点中触发)。

The following example shows this:以下示例显示了这一点:

>>> d = {1: 0, 2: 42}

>>> 1 in d
True

>>> if d.get(1): print("yes")
...

>>> 2 in d
True

>>> if d.get(2): print("yes")
...
yes

If, as it seems, you're just trying to establish whether a key exists, the key in dict method is the correct way to go (you don't really care what the value is, just whether the value exists).如果看起来你只是想确定一个键是否存在,那么key in dict是 go 的正确方法(你并不关心值是什么,只关心值是否存在)。

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

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