복붙노트

[PYTHON] 키가 사전에 있는지 확인 [중복]

PYTHON

키가 사전에 있는지 확인 [중복]

나는 파이썬 사전을 가지고있다 :

mydict = {'name':'abc','city':'xyz','country','def'}

키가 사전에 있는지 아닌지 확인하고 싶습니다. 나는 다음 두 가지 경우에서 더 바람직한 것을 알고 싶어합니다. 왜 그런가요?

1> if mydict.has_key('name'):
2> if 'name' in mydict:

해결법

  1. ==============================

    1.

    if 'name' in mydict:
    

    선호되는 pythonic 버전입니다. has_key ()의 사용은 권장되지 않으며,이 메소드는 Python 3에서 삭제되었습니다.

  2. ==============================

    2.마티노의 반응과 동일한 맥락에서 가장 좋은 해결책은 종종 확인하지 않는 것입니다. 예를 들어, 코드

    마티노의 반응과 동일한 맥락에서 가장 좋은 해결책은 종종 확인하지 않는 것입니다. 예를 들어, 코드

    if x in d:
        foo = d[x]
    else:
        foo = bar
    

    보통 쓰여있다

    foo = d.get(x, bar)
    

    더 짧고 더 직접적으로 당신이 의미하는 바를 말합니다.

    또 다른 일반적인 경우는 다음과 같습니다.

    if x not in d:
        d[x] = []
    
    d[x].append(foo)
    

    다시 쓸 수있다.

    d.setdefault(x, []).append(foo)
    

    또는 d에 대해 collections.defaultdict (list)를 사용하여 작성하고 작성하는 것이 더 낫습니다.

    d[x].append(foo)
    
  3. ==============================

    3.in은 바이트 코드의 관점에서 LOAD_ATTR을 저장하고 CALL_FUNCTION을 COMPARE_OP로 바꿉니다.

    in은 바이트 코드의 관점에서 LOAD_ATTR을 저장하고 CALL_FUNCTION을 COMPARE_OP로 바꿉니다.

    >>> dis.dis(indict)
      2           0 LOAD_GLOBAL              0 (name)
                  3 LOAD_GLOBAL              1 (d)
                  6 COMPARE_OP               6 (in)
                  9 POP_TOP             
    
    
    >>> dis.dis(haskey)
      2           0 LOAD_GLOBAL              0 (d)
                  3 LOAD_ATTR                1 (haskey)
                  6 LOAD_GLOBAL              2 (name)
                  9 CALL_FUNCTION            1
                 12 POP_TOP             
    

    내 감정은 in이 훨씬 더 읽기 쉽고 내가 생각할 수있는 모든 경우에 선호된다는 것입니다.

    성능 측면에서 타이밍은 opcode를 반영합니다.

    $ python -mtimeit -s'd = dict((i, i) for i in range(10000))' "'foo' in d"
     10000000 loops, best of 3: 0.11 usec per loop
    
    $ python -mtimeit -s'd = dict((i, i) for i in range(10000))' "d.has_key('foo')"
      1000000 loops, best of 3: 0.205 usec per loop
    

    in은 거의 두 배 빠릅니다.

  4. ==============================

    4.내 대답은 "둘 다".

    내 대답은 "둘 다".

    나는 일을하는 가장 "파이썬적인"방법은 키가 사전에 있는지 사전에 확인하지 않고 대신에 그 코드가 있다고 가정하는 코드를 작성하고 그것이 발생하지 않았기 때문에 제기 된 KeyErrors를 잡는 것이라고 믿습니다.

    이것은 대개 try ... except 절에 코드를 묶는 것으로 끝나며 일반적으로 "용서보다는 허가를 요청하는 것이 더 쉽다"또는 약어 EAFP로 표현되는 잘 알려진 관용구입니다. EAFP는 기본적으로 무언가를 시도하는 것이 더 좋습니다 무엇이든하기 전에 모든 것을 확인하기 위해 오류를 잡으십시오. 예외를 피하려고 시도하는 대신 정상적으로 예외를 처리 할 수있을 때 유효성을 검사 할 필요가없는 것을 검증하는 이유는 무엇입니까? 확률이 낮 으면 키가 없기 때문에 코드가 더 읽기 쉽고 코드가 더 빠르게되는 경향이 있습니다 (또는 전제 조건이있을 수도 있음).

    물론 이것은 모든 상황에 적절하지 않으며 모든 사람이 철학에 동의하는 것은 아니므로 사례별로 결정해야합니다. 당연히 이것의 반대는 "너를 도약하기 전에보십시오"를 위해 LBYL에게 불린다.

    간단한 예제로서 다음을 고려하십시오.

    if 'name' in dct:
        value = dct['name'] * 3
    else:
        logerror('"%s" not found in dictionary, using default' % name)
        value = 42
    

    try:
        value = dct['name'] * 3
    except KeyError:
        logerror('"%s" not found in dictionary, using default' % name)
        value = 42
    

    이 경우 코드의 양과 거의 같지만 두 번째 코드는 처음에는 시간을 확인하지 않아서 약간 빠릅니다 (try ... 블록은 완전히 무료가 아니기 때문에 아마 그렇지 않습니다). 여기서 큰 차이를 만들어라.)

    일반적으로 사전 테스트는 훨씬 더 복잡 할 수 있으며이를 수행하지 않을 경우 절약 효과가 상당 할 수 있습니다. 즉, dict의 'name'이 다른 답변에 나와있는 이유로 더 좋습니다.

    이 주제에 관심이 있다면,이 메시지는 "EAFP vs LBYL (지금까지는 조금 실망했습니다)"라는 파이썬 메일 링리스트 아카이브의 메시지가 아마도 제가 여기있는 것보다 더 다가간 것 같다고 설명 할 것입니다. Python in a Nutshell, Alex Martelli의 "Error-Checking Strategies"예외에 관한 장의 두 가지 접근법에 대한 좋은 토론도 있습니다.

  5. from https://stackoverflow.com/questions/3733992/determine-whether-a-key-is-present-in-a-dictionary by cc-by-sa and MIT license