如何为Python的defaultdict基于键生成对应值?
如何为Python的defaultdict基于键生成对应值?
这个问题问得好!其实你一开始的写法行不通,是因为defaultdict的默认工厂函数是不带参数的——当你访问一个不存在的键时,它只会调用你传入的lambda,不会把当前的键传进去,所以你写的lambda key=None: key*2里的key永远是None,执行d[1]会得到None*2=0,完全不是你想要的结果。
那怎么实现基于键生成默认值呢?最优雅的方式是继承defaultdict,重写它的__missing__方法。这个方法专门负责处理字典中不存在的键,参数就是当前访问的那个键,我们可以在里面定义任意基于键的计算逻辑,然后把值存入字典再返回。
比如你想要的“键乘2”的需求,可以这么写:
from collections import defaultdict class KeyBasedDefaultDict(defaultdict): def __missing__(self, key): # 这里写你需要的键的处理逻辑 value = key * 2 self[key] = value # 把计算好的值存入字典 return value # 测试一下 d = KeyBasedDefaultDict() print(d[1]) # 输出 2 print(d[3]) # 输出 6 print(d) # 输出 {1: 2, 3: 6}
这种方法的好处是完全保留了defaultdict的所有原有特性,只是定制了默认值的生成规则。你还可以根据需要修改逻辑,比如如果键是字符串就转大写,是数字就取平方:
class KeyBasedDefaultDict(defaultdict): def __missing__(self, key): if isinstance(key, str): value = key.upper() elif isinstance(key, int): value = key ** 2 else: value = key # 其他类型直接返回原键 self[key] = value return value d = KeyBasedDefaultDict() print(d["test"]) # 输出 TEST print(d[4]) # 输出 16 print(d[True]) # 输出 True
如果不想写类,其实也可以用普通字典重写__getitem__方法,但继承defaultdict是最清晰、最符合Python风格的做法。
备注:内容来源于stack exchange,提问作者J. Doe
相关产品推荐
相关产品推荐

