python字典中的keyError

Sac*_*rma 2 python dictionary python-3.x

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
Run Code Online (Sandbox Code Playgroud)

错误:KeyError:“ j”

小智 8

在您的情况下,发生KeyError的原因是您试图访问不在词典中的键。最初,字典是空的。因此,其中没有任何键。

如果您来自C ++背景,这似乎很奇怪,因为C ++映射会为尚不存在的键提供默认值。您可以使用来在python中获得相同的行为collections.defaultdict。修改后的代码如下。我在代码末尾自由地将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
Run Code Online (Sandbox Code Playgroud)

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

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

    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
    
    Run Code Online (Sandbox Code Playgroud)
  • 使用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)
    
    Run Code Online (Sandbox Code Playgroud)
  • 使用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
    
    Run Code Online (Sandbox Code Playgroud)
  • 由于您的代码实际上只是在计算每个字符的频率,因此您还可以使用collections.Counter然后将其转换为字典:

    from collections import Counter
    patt='jkasb'
    
    character_counter = Counter(patt)
    
    my_dict = dict(character_counter)
    
    Run Code Online (Sandbox Code Playgroud)

另外,因为dict是内置数据类型,并且我使用dict将defaultdict和Counter转换为普通字典,所以我将字典的名称从dict更改为my_dict。


MrG*_*eek 5

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

d[i] = 1 if i not in d else d[i] + 1
Run Code Online (Sandbox Code Playgroud)

替代方案(针对您要完成的任务):

使用dict.get

d[i] = d.get(i, 0) + 1
Run Code Online (Sandbox Code Playgroud)

使用collections.defaultdict

from collections import defaultdict
d = defaultdict(int)
for i in 'jkasb':
    d[i] += 1
Run Code Online (Sandbox Code Playgroud)

使用collections.Counter

from collections import Counter
d = Counter('jkasb')
Run Code Online (Sandbox Code Playgroud)

避免使用dict(built-in type) 作为变量名。只需迭代'jkasb'而不必将其转换为列表,字符串也是可迭代的。