관용구와 가독성에 대한 질문이 있는데,이 경우에 파이썬 철학이 충돌하는 것 같습니다.
사전 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에 어떻게 적용되는지 모릅니다.