【问题标题】:python dictionary keyErrorpython字典keyError
【发布时间】:2019-09-01 15:45:44
【问题描述】:

python 新手,看似简单可行的代码产生KeyError

patt=list('jkasb')

dict={}
for i in patt:
    dict[i]= 1 if dict[i] is None else dict[i]+1 # This line throws error

错误:KeyError:'j'

【问题讨论】:

  • if dict[i] is None 引发错误,因为还没有 dict[i]
  • 另外,不要给你的变量命名为内置函数(比如dict,这里)

标签: python python-3.x dictionary


【解决方案1】:

在构建字典 dict 时,dict[i] 正在尝试访问一个尚不存在的键,为了检查字典中是否存在键,请改用 in 运算符:

d[i] = 1 if i not in d else d[i] + 1

替代方案(你想要完成的事情):

使用dict.get:

d[i] = d.get(i, 0) + 1

使用collections.defaultdict:

from collections import defaultdict
d = defaultdict(int)
for i in 'jkasb':
    d[i] += 1

使用collections.Counter:

from collections import Counter
d = Counter('jkasb')

避免使用dict(内置类型)作为变量名。只需迭代 'jkasb' 而无需将其转换为列表,字符串也是可迭代的。

【讨论】:

    【解决方案2】:

    在您的情况下,发生 KeyError 是因为您尝试访问不在字典中的键。最初,字典是空的。因此,其中不存在任何键。

    如果您来自 C++ 背景,这可能看起来很奇怪,因为 C++ 映射为尚不存在的键提供默认值。您可以使用collections.defaultdict 在python 中获得相同的行为。修改后的代码如下。我冒昧地将 defaultdict 转换为代码末尾的常规字典:

    from collections import defaultdict
    patt='jkasb'
    
    my_default_dict=defaultdict(int)
    for i in patt:
        my_default_dict[i]+=1
    
    my_dict = dict(my_default_dict) # converting the defaultdict to a regular dictionary
    

    您还可以通过多种其他方式解决此问题。我在下面展示了其中的一些:

    • 通过检查键是否存在于字典中:

      patt='jkasb'
      
      my_dict={}
      for i in patt:
          my_dict[i]= 1 if i not in my_dict else my_dict[i]+1 # checking if i exists in dict
      
    • 使用不带默认返回值的dict.get()

      patt='jkasb'
      
      my_dict={}
      for i in patt:
          my_dict[i]= 1 if my_dict.get(i) is None else my_dict[i]+1 # using dict.get
      print(my_dict)
      
    • dict.get() 与默认返回值一起使用:

      patt='jkasb'
      
      my_dict={}
      for i in patt:
          my_dict[i]= my_dict.get(i, 0)+1 # using dict.get with default return value 0
      
    • 由于您的代码实际上只是计算每个字符的频率,因此您也可以使用collections.Counter,然后将其转换为字典:

      from collections import Counter
      patt='jkasb'
      
      character_counter = Counter(patt)
      
      my_dict = dict(character_counter)
      

    另外,由于 dict 是一种内置数据类型,我使用 dict 将 defaultdict 和 Counter 转换为普通字典,因此我将字典名称从 dict 更改为 my_dict。

    【讨论】:

      【解决方案3】:

      由于您的dict 最初为空,因此尝试使用dict[i] 访问任何值都会抛出KeyError

      你应该用 .get() 替换它,如果找不到密钥,则返回 None

      for i in patt:
          dict[i] = 1 if dict.get(i) is None else dict[i] + 1
      

      正如@snakecharmerb 所建议的,另一种选择是事先检查您的字典中是否存在密钥:

      for i in patt:
          dict[i] = 1 if i not in dict else dict[i] + 1
      

      两种解决方案是等价的,但第二种可能更“惯用”。

      【讨论】:

      • 或者干脆dict[i] = dict.get(i, 0) + 1
      • 知道了。 Dint 知道他们让 dict[] 和 dict.get 有不同的行为。
      【解决方案4】:

      这些 sn-ps:dict[i]dict[i]+1 将尝试使用对应的键 i 从字典中获取一个值。由于您的字典中没有任何内容,因此您会收到 KeyError。

      【讨论】:

        【解决方案5】:

        您正在尝试访问空字典中的键,您也可以使用defaultdic,这样您就不必关心该键是否已经存在:

        from collections import defaultdict
        
        patt=list('jkasb')
        
        my_dict = defaultdict(int) 
        for i in patt:
           my_dict[i] += 1 
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-04-29
          • 1970-01-01
          • 2021-01-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多