使用印地语(Devanagari)作为字典键时触发KeyError的问题排查
问题分析与解决
咱们先拆解两段代码的核心差异,就能明白为啥一个正常运行、一个触发KeyError了:
为什么两段代码表现不同?
第一段代码里,你用了collections.defaultdict(dict),然后直接执行word_count[st][st_1] = 1——这里的逻辑是:
- 当
st不在外层的defaultdict里时,defaultdict会自动创建一个空的普通dict作为它的值 - 随后直接给这个普通
dict的st_1键赋值,这一步完全合法:普通dict允许直接新增不存在的键值对,不会报错
但第二段代码的逻辑不一样:
你先写了if(P[i][j] >= 0),这时候P[i]确实会被defaultdict自动创建成空dict,但这个内层的dict是普通dict,不是带默认值的defaultdict。当你访问P[i][j]时,因为j这个键还不存在,普通dict就会直接抛出KeyError,根本到不了后续的赋值步骤。
报错信息里的'\xe0\xa4\x85\xe0\xa4\xaa\xe0\xa4\xa8\xe0\xa5\x87',其实就是印地语अपने的字节编码,印证了确实是找不到这个键导致的错误。
解决方法
有几种方案可以选,适配不同的需求场景:
方案1:内层也用defaultdict(int)(最推荐)
既然是做计数逻辑,内层用defaultdict(int)最省心——它会把不存在的键默认值设为0,完美适配累加需求:
#!/usr/bin/env python #-*- coding: utf-8 -*- from collections import defaultdict P = defaultdict(lambda: defaultdict(int)) # 内层嵌套defaultdict(int) i = "your" j = "अपने" P[i][j] += 1 # 直接累加即可,默认初始值为0 print(P)
这样哪怕P[i][j]之前不存在,也会自动初始化为0再执行加1操作,完全不会触发KeyError。
方案2:用dict.get()方法给默认值
如果不想修改内层结构,也可以用普通dict的get方法,指定键不存在时的默认值:
#!/usr/bin/env python #-*- coding: utf-8 -*- from collections import defaultdict P = defaultdict(dict) i = "your" j = "अपने" current_count = P[i].get(j, 0) # 键不存在时返回0 P[i][j] = current_count + 1 print(P)
方案3:先判断键是否存在
最直观的写法,先检查内层dict里有没有目标键:
#!/usr/bin/env python #-*- coding: utf-8 -*- from collections import defaultdict P = defaultdict(dict) i = "your" j = "अपने" if j in P[i]: P[i][j] += 1 else: P[i][j] = 1 # 这里建议初始化为1,原代码的0可能是笔误,可根据实际需求调整 print(P)
内容的提问来源于stack exchange,提问作者SilentFlame
相关产品推荐
相关产品推荐

