【问题标题】:Why KeyError raises even the respective key exists?为什么 KeyError 会引发即使相应的键存在?
【发布时间】:2020-01-18 02:38:02
【问题描述】:
def countLetter(string):
    dic = dict()
    for char in string:
        dic[char] = (1,dic[char]+1)[char in dic]
    print(dic)
countLetter('aabcb')

在这里,我试图计算每个字母出现的次数,但第 4 行引发了错误。 它会引发 KeyError

【问题讨论】:

  • “连各自的key都存在吗?” 不存在。这就是您收到KeyError 的原因。当您创建 dic 时,它是空的,并且在您已经尝试访问该分配右侧的 dic[char] 的值之前,您不会尝试在 dic[char] 添加任何内容。跨度>
  • 但是,只有在条件为真时才会评估。并且条件是检查字典中键的存在
  • 它是无条件评估的,因为你没有在任何地方写if
  • @kaya3:从技术上讲,如果没有if,您仍然可以进行惰性评估,例如在PEP 308 之前通过旧的(容易出错,但在这种情况下可以使用)方法在两个选项之间进行选择:dic[char] = char in dic and dic[char] + 1 or 1
  • 是的,if 不是唯一有条件地求值的语言结构——如果你真的想的话,你甚至可以写 while condition: do_thing(); break。但是代码没有使用任何这样的结构,这就是重点。

标签: python-3.x keyerror


【解决方案1】:

问题在于这一行:

dic[char] = (1,dic[char]+1)[char in dic]

热切地评估dic[char]+1作为构建tuple索引的一部分之前您可以测试char in dic是否选择@的元素987654327@。因此,在您的测试有机会防止查找失败之前,它会以 KeyError 消失。为了让它变得懒惰,你可以这样做:

dic[char] = dic[char] + 1 if char in dic else 1

或者你可以使用a method designed for this 来避免显式测试:

dic[char] = dic.get(char, 0) + 1

尽管collections.Counter 使这种特殊模式变得更加简单:

import collections

def countLetter(string):
    print(collections.Counter(string))  # print(dict(collections.Counter(string))) if it must look like a dict

【讨论】:

  • 是的!惰性方法有效。但是,我不明白 get 方法是如何工作的?
  • @Surya:阅读我链接的文档。 get 从不引发异常;如果键不存在,则返回第二个参数(None,如果没有给出第二个参数)。
猜你喜欢
  • 2016-04-19
  • 2014-04-30
  • 2020-07-27
  • 2011-02-13
  • 1970-01-01
  • 2017-07-25
  • 1970-01-01
  • 1970-01-01
  • 2021-05-09
相关资源
最近更新 更多