파이썬에서 어떤 데이터 구조가 더 효율적 / 빠른가? 그 순서가 나에게 중요하지 않다고 가정하고 어쨌든 중복을 확인하려고한다면 파이썬이 파이썬 목록보다 느리게 설정됩니까?
파이썬에서 어떤 데이터 구조가 더 효율적 / 빠른가? 그 순서가 나에게 중요하지 않다고 가정하고 어쨌든 중복을 확인하려고한다면 파이썬이 파이썬 목록보다 느리게 설정됩니까?
답변:
그것은 당신이 그것을하려는 의도에 달려 있습니다.
세트에 객체가 있는지 여부를 판별 할 때 세트가 상당히 빠르지 x in s
만 컨텐츠를 반복 할 때 목록보다 속도가 느립니다.
timeit 모듈 을 사용 하여 상황에 맞는 것이 더 빠른지 확인할 수 있습니다.
값을 반복하려는 경우 목록이 세트보다 약간 빠릅니다.
그러나 항목이 포함되어 있는지 확인하려는 경우 세트가 목록보다 훨씬 빠릅니다. 그러나 고유 한 항목 만 포함 할 수 있습니다.
튜플은 불변성을 제외하고 목록과 거의 동일한 방식으로 수행됩니다.
반복
>>> def iter_test(iterable):
... for i in iterable:
... pass
...
>>> from timeit import timeit
>>> timeit(
... "iter_test(iterable)",
... setup="from __main__ import iter_test; iterable = set(range(10000))",
... number=100000)
12.666952133178711
>>> timeit(
... "iter_test(iterable)",
... setup="from __main__ import iter_test; iterable = list(range(10000))",
... number=100000)
9.917098999023438
>>> timeit(
... "iter_test(iterable)",
... setup="from __main__ import iter_test; iterable = tuple(range(10000))",
... number=100000)
9.865639209747314
물체가 있는지 확인
>>> def in_test(iterable):
... for i in range(1000):
... if i in iterable:
... pass
...
>>> from timeit import timeit
>>> timeit(
... "in_test(iterable)",
... setup="from __main__ import in_test; iterable = set(range(1000))",
... number=10000)
0.5591847896575928
>>> timeit(
... "in_test(iterable)",
... setup="from __main__ import in_test; iterable = list(range(1000))",
... number=10000)
50.18339991569519
>>> timeit(
... "in_test(iterable)",
... setup="from __main__ import in_test; iterable = tuple(range(1000))",
... number=10000)
51.597304821014404
목록 성능 :
>>> import timeit
>>> timeit.timeit(stmt='10**6 in a', setup='a = range(10**6)', number=100000)
0.008128150348026608
성능 설정 :
>>> timeit.timeit(stmt='10**6 in a', setup='a = set(range(10**6))', number=100000)
0.005674857488571661
Tuple 은 목록과 비슷하지만 수정할 수 없으므로 Tuple 을 고려할 수 있습니다. 메모리를 약간 덜 차지하고 액세스 속도가 더 빠릅니다. 융통성이 없지만 목록보다 효율적입니다. 일반적인 용도는 사전 키 역할을하는 것입니다.
세트는 또한 시퀀스 구조이지만 목록과 튜플과는 두 가지 차이점이 있습니다. 세트에는 순서가 있지만 순서는 임의적이며 프로그래머가 제어하지 않습니다. 두 번째 차이점은 세트의 요소가 고유해야한다는 것입니다.
>>> x = set([1, 1, 2, 2, 3, 3])
>>> x
{1, 2, 3}
set
내장 유형 링크 ( docs.python.org/2/library/stdtypes.html#set )로 업데이트해야합니다 sets
. 둘째, "세트는 시퀀스 구조이기도합니다."기본 제공 유형 링크에서 다음을 읽으십시오. "정렬되지 않은 콜렉션이므로 세트는 요소 위치 또는 삽입 순서를 기록하지 않습니다. 따라서 세트는 인덱싱, 슬라이싱 또는 기타를 지원하지 않습니다. 순서와 유사한 행동 "
range
아닙니다 list
. range
커스텀 __contains__
매직 메소드 가있는 특수 클래스입니다 .
xrange
)
Set
거의 즉각적인 '포함'점검으로 인해 승리 : https://en.wikipedia.org/wiki/Hash_table
목록 구현 : 일반적으로 금속에 가까운 낮은 수준의 배열로, 반복 및 요소 인덱스 별 임의 액세스에 적합합니다.
구현 설정 : https://en.wikipedia.org/wiki/Hash_table , 목록에서 반복하지 않지만 키에서 해시 를 계산하여 요소를 찾으 므로 키 요소의 특성과 해시에 따라 다릅니다. 함수. dict에 사용되는 것과 유사합니다. 내가 의심 list
당신은 매우 몇 가지 요소 (<5)이있는 경우 더 빨리 될 수있다, 더 큰 요소는 더 카운트 set
A가 수표를 포함하기위한 수행합니다. 또한 요소 추가 및 제거가 빠릅니다. 또한 세트를 만드는 데 비용이 든다는 사실을 항상 명심하십시오!
참고 : list
가 이미 정렬되어 있으면 검색 list
이 매우 빠를 수 있지만 일반적인 경우 set
에는 포함 검사가 더 빠르고 간단합니다.
그들은 기본적 의미 데이터에 대한 작업을 수행하는 데 사용되기 때문에 데이터 구조 (DS)가 중요하다 : 약간의 입력을 받아 , 그것을 처리 및 출력을 돌려주고 .
일부 데이터 구조는 특정 경우에 다른 데이터 구조보다 유용합니다. 따라서 어떤 (DS)가 더 효율적 / 빠른지 묻는 것은 불공평합니다. 나이프와 포크 사이에서 어떤 도구가 더 효율적인지 묻는 것과 같습니다. 나는 모든 상황에 달려 있습니다.
목록은 변경 가능한 순서 이며 일반적으로 동종 항목의 컬렉션을 저장하는 데 사용됩니다 .
집합 객체는 고유 한 해시 가능 객체 의 정렬되지 않은 모음입니다 . 일반적으로 멤버십을 테스트하고 시퀀스에서 중복을 제거하고 교점, 합집합, 차이 및 대칭 차이와 같은 수학 연산을 계산하는 데 사용됩니다.
일부 답변에서 값을 반복 할 때 목록이 세트보다 훨씬 빠릅니다. 반면에 항목이 포함되어 있는지 확인할 때 목록보다 세트가 더 빠릅니다. 따라서 말할 수있는 유일한 것은 목록이 특정 작업에 대한 집합보다 낫다는 것입니다.
값이 소수의 리터럴 중 하나인지 CPython을 사용하여 확인할 때 결과에 관심이있었습니다. set
대 파이썬 3으로 승리 tuple
, list
그리고 or
:
from timeit import timeit
def in_test1():
for i in range(1000):
if i in (314, 628):
pass
def in_test2():
for i in range(1000):
if i in [314, 628]:
pass
def in_test3():
for i in range(1000):
if i in {314, 628}:
pass
def in_test4():
for i in range(1000):
if i == 314 or i == 628:
pass
print("tuple")
print(timeit("in_test1()", setup="from __main__ import in_test1", number=100000))
print("list")
print(timeit("in_test2()", setup="from __main__ import in_test2", number=100000))
print("set")
print(timeit("in_test3()", setup="from __main__ import in_test3", number=100000))
print("or")
print(timeit("in_test4()", setup="from __main__ import in_test4", number=100000))
산출:
tuple
4.735646052286029
list
4.7308746771886945
set
3.5755991376936436
or
4.687681658193469
3 ~ 5 리터럴의 경우 set
여전히 넓은 마진으로 이기고 or
가장 느립니다.
파이썬 2에서는 set
항상 느립니다. or
2 ~ 3 리터 가장 빠른, 그리고 tuple
하고 list
있습니다 빠른 4 개 이상 리터럴. tuple
대 속도를 구분할 수 없었습니다 list
.
테스트 할 값이 루프 내에서 리터럴을 생성하는 대신 함수 외부의 전역 변수에 캐시되면 set
Python 2에서도 매번 승리했습니다.
이 결과는 Core i7의 64 비트 CPython에 적용됩니다.
from datetime import datetime
listA = range(10000000)
setA = set(listA)
tupA = tuple(listA)
#Source Code
def calc(data, type):
start = datetime.now()
if data in type:
print ""
end = datetime.now()
print end-start
calc(9999, listA)
calc(9999, tupA)
calc(9999, setA)
3 개 모두에 대해 10 회 반복을 비교 한 결과 : 비교
세트는 더 빠르며, Morover는 세트가 더 많은 기능을 얻습니다.
set1 = {"Harry Potter", "James Bond", "Iron Man"}
set2 = {"Captain America", "Black Widow", "Hulk", "Harry Potter", "James Bond"}
우리는 쉽게 두 세트에 합류 할 수 있습니다 :
set3 = set1.union(set2)
두 가지 공통점이 무엇인지 알아보십시오.
set3 = set1.intersection(set2)
둘 다의 차이점을 찾으십시오.
set3 = set1.difference(set2)
그리고 훨씬 더! 그냥 사용해보십시오, 그들은 재미 있습니다! 또한 2 목록 내의 다른 값이나 2 목록 내의 공통 값에 대해 작업 해야하는 경우 목록을 세트로 변환하는 것을 선호하며 많은 프로그래머가 그렇게합니다. 그것이 도움이되기를 바랍니다 :-)