我想用其他人替换一些罕见的输入,即我的过程将清理'以某种方式输入。我目前的解决方案是覆盖dict.__getitem__
并维护一个小例外字典(最多几十个)。
class RDict(dict):
def __init__(self, *args):
dict.__init__(self, args)
def __getitem__(self, key):
try:
return dict.__getitem__(self, key):
except KeyError:
return key
但这感觉很难看,首先是因为我在正常情况下使用例外情况。 case,但其次是因为它似乎是一种实现相当简单效果的代码。我从defaultdict
尝试了collections
,但这需要一个无参数函数,即默认值不能依赖于输入项,只能在一些可能非严格的函数调用上。注:我正在寻找一个通用的解决方案,而不是特定类型(例如字符串)的解决方案。
(我在撰写问题时解决了我自己的问题,但我仍在发帖,因为我很好奇是否有内置,标准或者只是特别整洁/有效的方法。)
答案 0 :(得分:1)
显而易见的解决方案是直接使用字典,其中只有dict.get
方法用于此类场合:
DIRTY.get(x, x)
根据您的评论,我使用timeit
进行了快速测试:
>>> import timeit
>>> def dict_get_direct(d, x):
return d.get(x, x)
>>> def dict_get_manual(d, x):
if x in d:
return d[x]
return x
>>> timeit.timeit("dict_get_direct({1:2, 3:4}, 1)", setup="from __main__ import dict_get_manual, dict_get_direct")
0.48331750281312225
>>> timeit.timeit("dict_get_direct({1:2, 3:4}, 5)", setup="from __main__ import dict_get_manual, dict_get_direct")
0.45923153755705926
>>> timeit.timeit("dict_get_manual({1:2, 3:4}, 1)", setup="from __main__ import dict_get_manual, dict_get_direct")
0.45144323770750816
>>> timeit.timeit("dict_get_manual({1:2, 3:4}, 5)", setup="from __main__ import dict_get_manual, dict_get_direct")
0.40186868623015926
>>> timeit.timeit("{1:2, 3:4}.get(1, 1)", setup="from __main__ import dict_get_manual, dict_get_direct")
0.3100665514014622
>>> timeit.timeit("{1:2, 3:4}.get(5, 5)", setup="from __main__ import dict_get_manual, dict_get_direct")
0.2964287294703354
我看到这两个函数的性能相似("手册"版本稍微快一点,尤其是所有未命中),但很明显,如果你可以内联dict.get
而不是调用函数它& #39;快得多。
答案 1 :(得分:0)
在写这个问题的同时,我找到了两个解决方案(或者更确切地说是一个可以用来改进我以前解决方案的解决方案)。 这样做的显而易见的方法是
def clean(x):
if x in DIRTY:
return DIRTY[x]
return x
但是如果我想要一个类似字典的界面那么
class RDict(dict):
def __init__(self, *args):
dict.__init__(self, args)
def __getitem__(self, key):
if key in self
return dict.__getitem__(self, key):
return key
结果是我原来建议的两倍多(尽管比清洁功能慢三倍)。