[PYTHON] 사전 및 기본값
PYTHON사전 및 기본값
connectionDetails가 파이썬 사전이라고 가정하면 이처럼 코드를 리팩토링하는 데 가장 훌륭하고 가장 우아하고 파이썬적인 방법은 무엇일까요?
if "host" in connectionDetails:
host = connectionDetails["host"]
else:
host = someDefaultValue
해결법
-
==============================
1.이렇게 :
이렇게 :
host = connectionDetails.get('host','someDefault')
-
==============================
2.다음과 같이 defaultdict를 사용할 수도 있습니다 :
다음과 같이 defaultdict를 사용할 수도 있습니다 :
from collections import defaultdict a = defaultdict(lambda: "default", key="some_value") a["blabla"] => "default" a["key"] => "some_value"
람다 대신 일반 함수를 전달할 수 있습니다 :
from collections import defaultdict def a(): return 4 b = defaultdict(a, key="some_value") b['absent'] => 4 b['key'] => "some_value"
-
==============================
3..get ()은 훌륭한 숙어이지만, if / else보다 속도가 느립니다. (사전에서 키의 존재가 대부분 예상 될 수있는 경우를 제외하고 try / except보다 느립니다) :
.get ()은 훌륭한 숙어이지만, if / else보다 속도가 느립니다. (사전에서 키의 존재가 대부분 예상 될 수있는 경우를 제외하고 try / except보다 느립니다) :
>>> timeit.timeit(setup="d={1:2, 3:4, 5:6, 7:8, 9:0}", ... stmt="try:\n a=d[1]\nexcept KeyError:\n a=10") 0.07691968797894333 >>> timeit.timeit(setup="d={1:2, 3:4, 5:6, 7:8, 9:0}", ... stmt="try:\n a=d[2]\nexcept KeyError:\n a=10") 0.4583777282275605 >>> timeit.timeit(setup="d={1:2, 3:4, 5:6, 7:8, 9:0}", ... stmt="a=d.get(1, 10)") 0.17784020746671558 >>> timeit.timeit(setup="d={1:2, 3:4, 5:6, 7:8, 9:0}", ... stmt="a=d.get(2, 10)") 0.17952161730158878 >>> timeit.timeit(setup="d={1:2, 3:4, 5:6, 7:8, 9:0}", ... stmt="if 1 in d:\n a=d[1]\nelse:\n a=10") 0.10071221458065338 >>> timeit.timeit(setup="d={1:2, 3:4, 5:6, 7:8, 9:0}", ... stmt="if 2 in d:\n a=d[2]\nelse:\n a=10") 0.06966537335119938
-
==============================
4.여러 다른 기본값의 경우 다음을 시도하십시오.
여러 다른 기본값의 경우 다음을 시도하십시오.
connectionDetails = { "host": "www.example.com" } defaults = { "host": "127.0.0.1", "port": 8080 } completeDetails = {} completeDetails.update(defaults) completeDetails.update(connectionDetails) completeDetails["host"] # ==> "www.example.com" completeDetails["port"] # ==> 8080
-
==============================
5.파이썬 사전에 이렇게하는 방법이 있습니다 : dict.setdefault
파이썬 사전에 이렇게하는 방법이 있습니다 : dict.setdefault
connectionDetails.setdefault('host',someDefaultValue) host = connectionDetails['host']
그러나이 메소드는 키 호스트가 아직 정의되지 않은 경우 connectionDetails [ 'host']의 값을 someDefaultValue로 설정합니다.
-
==============================
6.(이것은 늦은 대답이다)
(이것은 늦은 대답이다)
대안은 dict 클래스를 서브 클래스 화하고 다음과 같이 __missing __ () 메소드를 구현하는 것입니다.
class ConnectionDetails(dict): def __missing__(self, key): if key == 'host': return "localhost" raise KeyError(key)
예 :
>>> connection_details = ConnectionDetails(port=80) >>> connection_details['host'] 'localhost' >>> connection_details['port'] 80 >>> connection_details['password'] Traceback (most recent call last): File "python", line 1, in <module> File "python", line 6, in __missing__ KeyError: 'password'
-
==============================
7.Python 3.3.5에서 PyPy (5.2.0-alpha0)의 상황에 대한 @Tim Pietzcker의 의혹을 테스트 한 결과, .get ()과 if / else 방식이 비슷하게 작동한다는 것을 알았습니다. 사실 if / else의 경우에는 조건과 할당이 동일한 키를 포함하는 경우 (심지어 두 개의 조회가있는 마지막 사례와 비교) 단 하나의 조회 만있는 것으로 보입니다.
Python 3.3.5에서 PyPy (5.2.0-alpha0)의 상황에 대한 @Tim Pietzcker의 의혹을 테스트 한 결과, .get ()과 if / else 방식이 비슷하게 작동한다는 것을 알았습니다. 사실 if / else의 경우에는 조건과 할당이 동일한 키를 포함하는 경우 (심지어 두 개의 조회가있는 마지막 사례와 비교) 단 하나의 조회 만있는 것으로 보입니다.
>>>> timeit.timeit(setup="d={1:2, 3:4, 5:6, 7:8, 9:0}", .... stmt="try:\n a=d[1]\nexcept KeyError:\n a=10") 0.011889292989508249 >>>> timeit.timeit(setup="d={1:2, 3:4, 5:6, 7:8, 9:0}", .... stmt="try:\n a=d[2]\nexcept KeyError:\n a=10") 0.07310474599944428 >>>> timeit.timeit(setup="d={1:2, 3:4, 5:6, 7:8, 9:0}", .... stmt="a=d.get(1, 10)") 0.010391917996457778 >>>> timeit.timeit(setup="d={1:2, 3:4, 5:6, 7:8, 9:0}", .... stmt="a=d.get(2, 10)") 0.009348208011942916 >>>> timeit.timeit(setup="d={1:2, 3:4, 5:6, 7:8, 9:0}", .... stmt="if 1 in d:\n a=d[1]\nelse:\n a=10") 0.011475925013655797 >>>> timeit.timeit(setup="d={1:2, 3:4, 5:6, 7:8, 9:0}", .... stmt="if 2 in d:\n a=d[2]\nelse:\n a=10") 0.009605801998986863 >>>> timeit.timeit(setup="d={1:2, 3:4, 5:6, 7:8, 9:0}", .... stmt="if 2 in d:\n a=d[2]\nelse:\n a=d[1]") 0.017342638995614834
-
==============================
8.한 줄짜리 람바 (lamba) 함수를 사용할 수 있습니다. 함수처럼 액세스되는 새로운 객체 connectionDetails2 만들기 ...
한 줄짜리 람바 (lamba) 함수를 사용할 수 있습니다. 함수처럼 액세스되는 새로운 객체 connectionDetails2 만들기 ...
connectionDetails2 = lambda k: connectionDetails[k] if k in connectionDetails.keys() else "DEFAULT"
지금 사용하십시오.
connectionDetails2(k)
대신에
connectionDetails[k]
k가 키에 있으면 사전 값을 반환하고, 그렇지 않으면 "DEFAULT"를 반환합니다.
from https://stackoverflow.com/questions/9358983/dictionaries-and-default-values by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] 여러 프로세스간에 결과 큐 공유 (0) | 2018.10.07 |
---|---|
[PYTHON] Python super ()가 TypeError를 발생시킵니다. (0) | 2018.10.07 |
[PYTHON] 파이썬은 csv를 xlsx로 변환합니다. (0) | 2018.10.07 |
[PYTHON] 문자열에서 코드에서 모듈을로드하는 방법? (0) | 2018.10.07 |
[PYTHON] 파이썬 유니 코드 동일 비교 실패 (0) | 2018.10.07 |