清除稀有输入的有效方法

时间:2014-07-21 14:06:47

标签: python performance dictionary

我想用其他人替换一些罕见的输入,即我的过程将清理'以某种方式输入。我目前的解决方案是覆盖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,但这需要一个无参数函数,即默认值不能依赖于输入项,只能在一些可能非严格的函数调用上。注:我正在寻找一个通用的解决方案,而不是特定类型(例如字符串)的解决方案。

(我在撰写问题时解决了我自己的问题,但我仍在发帖,因为我很好奇是否有内置,标准或者只是特别整洁/有效的方法。)

2 个答案:

答案 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

结果是我原来建议的两倍多(尽管比清洁功能慢三倍)。