답변:
in
확실히 더 pythonic입니다.
keys()
복사본이 아닌 사전에 대한 설정과 유사한 뷰이므로 x in d.keys()
O (1)도 마찬가지 입니다. 아직도, x in d
더 파이썬입니다.
x in d.keys()
곳에서 메모리 할당을 완료하여 임시 객체를 구성하고 파괴해야 하기 때문이라고 생각합니다 x in d.keys()
. 참고 d.keys()
아직도 긴 정말 한이 아니라 10 배에 관한 것입니다. 나는 확인하지 않았지만 여전히 O (1) 만 확신합니다.
in
우아함뿐만 아니라 (더 이상 사용되지 않는 ;-) 성능뿐만 아니라 다음과 같이 손을 쓰지 않습니다.
$ python -mtimeit -s'd=dict.fromkeys(range(99))' '12 in d'
10000000 loops, best of 3: 0.0983 usec per loop
$ python -mtimeit -s'd=dict.fromkeys(range(99))' 'd.has_key(12)'
1000000 loops, best of 3: 0.21 usec per loop
다음과 같은 관찰이 항상 사실 은 아니지만 , 일반적으로 파이썬에서는 더 빠른 솔루션이 더 우아하고 Pythonic 임을 알 수 있습니다 . 그 이유 -mtimeit
는 아니다 - SO 도움이 단지 여기에 수백 나노초 저장 정보와이 -!)
has_key
O (1) 인 것 같습니다.
사용 dict.has_key()
하는 경우 (그리고 경우에만) 코드는 이전 2.3 이상 (때 파이썬 버전에서 실행 가능한 것이 요구된다 key in dict
도입되었다).
in
실제로 성능을 저하시키는 한 가지 예가 있습니다.
당신이 사용하는 경우 in
에만 구현하는 O에 (1) 컨테이너 __getitem__
및 has_key()
하지만,하지 __contains__
(당신은 O (1)는 O (N) 검색으로 검색 바뀝니다 in
통해 선형 검색을 다시 떨어진다 __getitem__
).
수정은 분명히 사소한 것입니다.
def __contains__(self, x):
return self.has_key(x)
has_key()
이다 파이썬이 사전에 특정한 . in
/ __contains__
는 올바른 API입니다. 전체 스캔이 불가피한 컨테이너의 경우 어쨌든has_key()
메소드 가 없으며 O (1) 접근 방식이 있으면 유스 케이스에 따라 다르므로 개발자가 문제에 대한 올바른 데이터 유형을 선택합니다.
has_key
는 사전 방법이지만 in
모든 컬렉션에서 작동하며 __contains__
누락 된 in
경우에도 다른 방법을 사용하여 컬렉션을 반복하여 찾을 수 있습니다.
in
테스트하는 것이 매우 효율적 range
입니다. xrange
그래도 Python 2 에서 의 효율성에 대해서는 잘 모르겠습니다 . ;)
__contains__
를 간단히 계산할 수 있습니다 .
range
매번 새 인스턴스 를 생성하는 오버 헤드가 포함 됩니다. 기존 의 단일 인스턴스를 사용하면 "정수 범위의 정수"테스트가 타이밍에서 약 40 % 빠릅니다.
dict.has_key () 솔루션은 더 이상 사용되지 않습니다. 'in'사용-숭고한 텍스트 편집기 3
여기서는 'ages'라는 사전의 예를 보았습니다.
ages = {}
# Add a couple of names to the dictionary
ages['Sue'] = 23
ages['Peter'] = 19
ages['Andrew'] = 78
ages['Karren'] = 45
# use of 'in' in if condition instead of function_name.has_key(key-name).
if 'Sue' in ages:
print "Sue is in the dictionary. She is", ages['Sue'], "years old"
else:
print "Sue is not in the dictionary"
Adam Parkin의 의견으로 Alex Martelli의 성능 테스트를 확장합니다 ...
$ python3.5 -mtimeit -s'd=dict.fromkeys(range( 99))' 'd.has_key(12)'
Traceback (most recent call last):
File "/usr/local/Cellar/python3/3.5.2_3/Frameworks/Python.framework/Versions/3.5/lib/python3.5/timeit.py", line 301, in main
x = t.timeit(number)
File "/usr/local/Cellar/python3/3.5.2_3/Frameworks/Python.framework/Versions/3.5/lib/python3.5/timeit.py", line 178, in timeit
timing = self.inner(it, self.timer)
File "<timeit-src>", line 6, in inner
d.has_key(12)
AttributeError: 'dict' object has no attribute 'has_key'
$ python2.7 -mtimeit -s'd=dict.fromkeys(range( 99))' 'd.has_key(12)'
10000000 loops, best of 3: 0.0872 usec per loop
$ python2.7 -mtimeit -s'd=dict.fromkeys(range(1999))' 'd.has_key(12)'
10000000 loops, best of 3: 0.0858 usec per loop
$ python3.5 -mtimeit -s'd=dict.fromkeys(range( 99))' '12 in d'
10000000 loops, best of 3: 0.031 usec per loop
$ python3.5 -mtimeit -s'd=dict.fromkeys(range(1999))' '12 in d'
10000000 loops, best of 3: 0.033 usec per loop
$ python3.5 -mtimeit -s'd=dict.fromkeys(range( 99))' '12 in d.keys()'
10000000 loops, best of 3: 0.115 usec per loop
$ python3.5 -mtimeit -s'd=dict.fromkeys(range(1999))' '12 in d.keys()'
10000000 loops, best of 3: 0.117 usec per loop
이와 같은 것이 있다면 :
t.has_key(ew)
Python 3.X 이상에서 실행하려면 아래로 변경하십시오.
key = ew
if key not in t
t.has_key(ew)
반환 True
합니다 ew
. key not in t
반환 True
값이있는 경우 하지 사전에. 또한 key = ew
별칭은 매우 중복됩니다. 올바른 철자는 if ew in t
입니다. 8 년 전의 답변이 이미 말한 내용입니다.