[python] `if key in dict` vs.`try / except`-어느 것이 더 읽기 쉬운 관용구입니까?

관용구와 가독성에 대한 질문이 있는데,이 경우에 파이썬 철학이 충돌하는 것 같습니다.

사전 B에서 사전 A를 만들고 싶습니다. 특정 키가 B에 없으면 아무 작업도 수행하지 않고 계속합니다.

어느 쪽이 더 낫습니까?

try:
    A["blah"] = B["blah"]
except KeyError:
    pass

또는

if "blah" in B:
    A["blah"] = B["blah"]

“용서를 구하고 구하라”대 “단순함과 명료 함”.

어느 것이 더 낫고 그 이유는 무엇입니까?



답변

예외는 조건부가 아닙니다.

조건부 버전이 더 명확합니다. 그것은 당연합니다. 이것은 단순한 흐름 제어이며, 예외가 아닌 조건문을 위해 설계된 것입니다.

예외 버전은 주로 루프에서 이러한 조회를 수행 할 때 최적화로 사용됩니다. 일부 알고리즘의 경우 내부 루프에서 테스트를 제거 할 수 있습니다. 여기에는 그 혜택이 없습니다. "blah"두 번 말하지 않아도된다는 작은 장점이 있지만, 이런 일을 많이한다면 move_key어차피 도우미 기능 이있을 것 입니다.

일반적으로 특별한 이유가없는 한 기본적으로 조건부 버전을 사용하는 것이 좋습니다. 조건문은 이를 수행 하는 명백한 방법이며 일반적으로 한 솔루션을 다른 솔루션보다 선호하는 강력한 권장 사항입니다.


답변

예외와 이중 조회를 모두 피하는 세 번째 방법도 있습니다. 조회 비용이 많이 드는 경우 중요 할 수 있습니다.

value = B.get("blah", None)
if value is not None:
    A["blah"] = value

경우에는 사전에 포함 할 것으로 예상 None당신이 좋아 좀 더 난해한 상수를 사용하여 값을 NotImplemented, Ellipsis또는 새로운 하나를 만들 :

MyConst = object()
def update_key(A, B, key):
    value = B.get(key, MyConst)
    if value is not MyConst:
        A[key] = value

어쨌든 사용 update()은 나에게 가장 읽기 쉬운 옵션입니다.

a.update((k, b[k]) for k in ("foo", "bar", "blah") if k in b)


답변

내가 이해하는 바에 따르면 dict B의 키, 값 쌍으로 dict A를 업데이트하고 싶습니다.

update 더 나은 선택입니다.

A.update(B)

예:

>>> A = {'a':1, 'b': 2, 'c':3}
>>> B = {'d': 2, 'b':5, 'c': 4}
>>> A.update(B)
>>> A
{'a': 1, 'c': 4, 'b': 5, 'd': 2}
>>> 


답변

Python 성능 위키에서 직접 인용 :

처음을 제외하고는 단어를 볼 때마다 if 문의 테스트가 실패합니다. 많은 수의 단어를 세는 경우 많은 단어가 여러 번 나올 것입니다. 값의 초기화가 한 번만 발생하고 해당 값의 증가가 여러 번 발생하는 상황에서는 try 문을 사용하는 것이 더 저렴합니다.

따라서 상황에 따라 두 가지 옵션이 모두 실행 가능한 것 같습니다. 자세한 내용은이 링크를 확인하시기 바랍니다 : Try-except-performance


답변

나는 여기에 일반적인 규칙이 A["blah"]일반적으로 존재할 것이라고 생각합니다. 그러면 try-except가 좋지 않으면 사용하십시오.if "blah" in b:

나는 “시도”가 시간적으로 저렴하다고 생각하지만 “예외”는 더 비싸다.


답변

두 번째 예제는이 코드가 이해가되지 않는 한 당신이 가야한다고 생각합니다.

try:
    A["foo"] = B["foo"]
    A["bar"] = B["bar"]
    A["baz"] = B["baz"]
except KeyError:
    pass

.NET Framework에없는 키가있는 즉시 코드가 중단됩니다 B. 이 코드가 의미가 있다면 예외 메서드를 사용해야하고 그렇지 않으면 테스트 메서드를 사용해야합니다. 제 생각에는 짧고 의도를 명확하게 표현하기 때문에 예외 메서드보다 읽기가 훨씬 쉽습니다.

물론 사용하라고 말하는 사람들 update이 맞습니다. 사전 이해를 지원하는 Python 버전을 사용하는 경우 다음 코드를 강력히 선호합니다.

updateset = {'foo', 'bar', 'baz'}
A.update({k: B[k] for k in updateset if k in B})


답변

다른 언어의 규칙은 예외적 인 조건, 즉 정기적으로 사용하지 않는 오류에 대한 예외를 예약하는 것입니다. 해당 규칙에 따라 StopIteration이 존재하지 않아야하므로 해당 규칙이 Python에 어떻게 적용되는지 모릅니다.