2011-01-04 3 views
3

파이썬 사전 액세스 메커니즘 "getitem"을 다시 작성하여 기본값을 반환 할 수 있습니다.python dicts를 다시 작성하여 기본값을 얻는 방법

내가 찾고 오전 기능이

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

힌트가 뭔가? 이미 collections.defaultdict 있습니다

감사

+1

또 다른 가능성은' – UncleZeiv

+0

예, 내가 그 일 개 덕분에 알고'a.get (100, 없음)를 사용하는 것입니다. 그러나 내 코드 전체에 그 코드를 가지고있는 것은 단지 추한 것입니다. – webDevelSouth

+0

누락 된 키를 없음으로 설정하거나 KeyError를 발생시키는 대신 None 만 반환하도록 하시겠습니까? – kevpie

답변

11

:

from collections import defaultdict 

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

람다는'lambda : None'이어야합니다. 그렇지 않으면'TypeError : ()이 정확히 1 개의 인수 (주어진 0)'을 취합니다. –

+0

@bukzor, Steven : 당신 말이 맞아요, 당신이 타이핑하는 동안 그것을 고칠 것 같습니다. –

3

파이썬 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 
+0

그리고 어떻게 defaultdict 사용을 피할 수 있을까요 ?? – webDevelSouth

+0

@webDevelSouth : 왜 defaultdict를 사용하지 않으시겠습니까? –

+0

나는 이것을 파이썬 OOP에 디딤돌로 사용하고 있다고 생각합니다. 나는 이것을 별도의 대답으로 썼다. – bukzor

1

사용 defaultdict 생성자에 인수가 기본 값을 반환하는 함수 인 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}) 
1

, 당신은 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 
+0

그리고 내가 스크립트의 상단에 사전으로 MyclassDefaultDict을 가져올 수 있다고 생각하고 나서 "dict"로 MyclassDefaultDict 수 - 내가 맞습니까 ?? – webDevelSouth

+4

음, 할 수는 있지만 할 수는 없습니다. 한 가지로, 중괄호를 사용하여 정의한 딕테이션의 경우에는 여전히 문제가되지 않습니다. '{ "foo": 1}'는'dict'을 다른 클래스로 재정의 한 경우에도 여전히 파이썬'dict'입니다. 또 다른 한 가지로, (6 개월 내에 자신을 포함하여) 코드를 관리하는 사람이'dict'을 본다면 정규 Python dict 유형이라고 가정합니다. – kindall

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 
관련 문제