Development Tip

defaultdict의 default_factory에 키를 전달하는 영리한 방법이 있습니까?

yourdevel 2020. 10. 7. 21:19
반응형

defaultdict의 default_factory에 키를 전달하는 영리한 방법이 있습니까?


클래스에는 하나의 매개 변수를 취하는 생성자가 있습니다.

class C(object):
    def __init__(self, v):
        self.v = v
        ...

코드 어딘가에서 dict의 값이 키를 알고 있으면 유용합니다.
신생아 기본값에 전달 된 키와 함께 defaultdict를 사용하고 싶습니다.

d = defaultdict(lambda : C(here_i_wish_the_key_to_be))

어떤 제안?


그것은 거의 자격 없다 영리한 -하지만 서브 클래스는 당신의 친구입니다 :

class keydefaultdict(defaultdict):
    def __missing__(self, key):
        if self.default_factory is None:
            raise KeyError( key )
        else:
            ret = self[key] = self.default_factory(key)
            return ret

d = keydefaultdict(C)
d[x] # returns C(x)

아니 없어.

defaultdict구현은 실종 통과 구성 할 수 없습니다 key받는 default_factory아웃 - 오브 - 박스. 유일한 옵션은 defaultdict위의 @JochenRitzel이 제안한대로 고유 한 하위 클래스 를 구현하는 것 입니다.

그러나 이것은 "영리"하거나 표준 라이브러리 솔루션만큼 깔끔하지 않습니다 (존재한다면). 따라서 귀하의 간결한 예 / 아니오 질문에 대한 대답은 분명히 "아니오"입니다.

표준 라이브러리에 자주 필요한 도구가 없다는 것은 너무 나쁩니다.


나는 당신이 defaultdict여기에 전혀 필요하지 않다고 생각합니다 . dict.setdefault방법을 사용하지 않는 이유

>>> d = {}
>>> d.setdefault('p', C('p')).v
'p'

물론 C. 문제가되는 경우 더 간단한 접근 방식이 효과가 있다고 생각합니다.

>>> d = {}
>>> if 'e' not in d: d['e'] = C('e')

defaultdict내가 볼 수있는 한 다른 대안 보다 빠를 것 입니다.

in테스트 속도 와 try-except 절 사용 에 관한 ETA :

>>> def g():
    d = {}
    if 'a' in d:
        return d['a']


>>> timeit.timeit(g)
0.19638929363557622
>>> def f():
    d = {}
    try:
        return d['a']
    except KeyError:
        return


>>> timeit.timeit(f)
0.6167065411074759
>>> def k():
    d = {'a': 2}
    if 'a' in d:
        return d['a']


>>> timeit.timeit(k)
0.30074866358404506
>>> def p():
    d = {'a': 2}
    try:
        return d['a']
    except KeyError:
        return


>>> timeit.timeit(p)
0.28588609450770264

참고URL : https://stackoverflow.com/questions/2912231/is-there-a-clever-way-to-pass-the-key-to-defaultdicts-default-factory

반응형