как переписать python dicts для получения значений по умолчанию - PullRequest
3 голосов
/ 04 января 2011

Я хочу переписать механизм доступа к словарю Python " getitem ", чтобы иметь возможность возвращать значения по умолчанию.

Функциональность, которую я ищу, похожа на

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

есть намеки?

Спасибо

Ответы [ 5 ]

11 голосов
/ 04 января 2011

Уже есть collections.defaultdict:

from collections import defaultdict

a = defaultdict(lambda:None)
print a[100]
3 голосов
/ 04 января 2011

Существует встроенный defaultdict начиная с Python 2.6. Конструктор принимает функцию, которая будет вызываться, когда значение не найдено. Это дает больше гибкости, чем просто возврат 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
1 голос
/ 04 января 2011

Если вы действительно не хотите использовать встроенный 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
1 голос
/ 04 января 2011

используйте defaultdict (http://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})
0 голосов
/ 04 января 2011

Я не знал о 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...