如何重写python dicts以获取默认值

时间:2011-01-04 18:24:40

标签: python dictionary

我想重写Python的字典访问机制“ getitem ”,以便能够返回默认值。

我正在寻找的功能类似于

a = dict()
a.setdefault_value(None)
print a[100] #this would return none

任何提示?

由于

5 个答案:

答案 0 :(得分:11)

已经有collections.defaultdict

from collections import defaultdict

a = defaultdict(lambda:None)
print a[100]

答案 1 :(得分:3)

从Python 2.6开始有一个defaultdict built-in。构造函数接受一个函数,当找不到值时将调用该函数。这比简单地返回None更具灵活性。

from collections import defaultdict

a = defaultdict(lambda: None)
print a[100] #gives None

lambda只是一种快速定义没有名称的单行函数的方法。此代码是等效的:

def nonegetter():
    return None

a = defaultdict(nonegetter)
print a[100] #gives None

这是一个非常有用的模式,它为您提供显示每个唯一对象计数的哈希值。使用普通的dict,你需要特殊的情况来避免KeyError。

counts = defaultdict(int)
for obj in mylist:
   counts[obj] += 1

答案 2 :(得分:1)

使用defaultdicthttp://docs.python.org/library/collections.html#collections.defaultdict

import collections
a = collections.defaultdict(lambda:None)

其中defaultdict构造函数的参数是一个返回默认值的函数。

请注意,如果您访问未设置的条目,它实际上将其设置为默认值:

>>> print a[100]
None
>>> a
defaultdict(<function <lambda> at 0x38faf0>, {100: None})

答案 3 :(得分:1)

如果确实想要不使用defaultdict内置,则需要定义自己的dict子类,如下所示:

class MyDefaultDict(dict):
    def setdefault_value(self, default):
        self.__default = default
    def __getitem__(self, key):
        try:
            return self[key]
        except IndexError:
            return self.__default

答案 4 :(得分:0)

我不知道defaultdict,这可能是最好的方法。如果你出于某种原因反对我过去曾为此目的写过小包装函数。功能稍有不同,可能会或可能不会更好。

def makeDictGet(d, defaultVal):
    return lambda key: d[key] if key in dict else defaultVal

使用它......

>>> d1 = {'a':1,'b':2}
>>> d1Get = makeDictGet(d1, 0)
>>> d1Get('a')
1
>>> d1Get(5)
0
>>> d1['newAddition'] = 'justAddedThisOne'    #changing dict after the fact is fine
>>> d1Get('newAddition')
'justAddedThisOne'
>>> del d1['a']
>>> d1Get('a')
0
>>> d1GetDefaultNone = makeDictGet(d1, None)   #having more than one such function is fine
>>> print d1GetDefaultNone('notpresent')
None
>>> d1Get('notpresent')
0
>>> f = makeDictGet({'k1':'val1','pi':3.14,'e':2.718},False) #just put new dict as arg if youre ok with being unable to change it or access directly
>>> f('e')
2.718
>>> f('bad')
False