Python Sets vs Lists

W Pythonie, która struktura danych jest bardziej wydajna/szybka? Zakładając, że kolejność nie jest dla mnie ważna i i tak sprawdzałbym duplikaty, czy zestaw Pythona jest wolniejszy niż lista Pythona?

Author: Mantas Vidutis, 2010-05-14

5 answers

To zależy od tego, co zamierzasz z nim zrobić.

Zbiory są znacznie szybsze, jeśli chodzi o określanie, czy obiekt jest obecny w zbiorze( jak w x in s), ale są wolniejsze niż listy, jeśli chodzi o iterację ich zawartości.

Możesz użyć timeit module , aby zobaczyć, który jest szybszy dla twojej sytuacji.

 164
Author: Michael Aaron Safyan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-29 10:25:14

Jeśli chcesz zapisać pewne wartości, które będziesz powtarzał, konstrukty list w Pythonie są nieco szybsze. Jeśli jednak będziesz przechowywać (unikalne) wartości w celu sprawdzenia ich istnienia, zestawy są znacznie szybsze.

Okazuje się, że krotki działają prawie dokładnie tak samo jak listy, ale zużywają mniej pamięci, usuwając możliwość ich modyfikacji po utworzeniu (niezmienne).

Iteracja

>>> 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

Określić, czy obiekt jest present

>>> 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
 112
Author: Ellis Percival,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-30 10:20:53

Wydajność listy:

>>> import timeit
>>> timeit.timeit(stmt='10**6 in a', setup='a = range(10**6)', number=100000)
0.008128150348026608

wydajność zestawu:

>>> timeit.timeit(stmt='10**6 in a', setup='a = set(range(10**6))', number=100000)
0.005674857488571661

Możesz rozważyć krotki , ponieważ są podobne do list, ale nie można ich modyfikować. Zajmują nieco mniej pamięci i są szybsze w dostępie. Nie są tak elastyczne, ale są bardziej wydajne niż listy. Ich normalne użycie ma służyć jako klucze słownikowe.

Zbiory są również strukturami sekwencji, ale z dwiema różnicami od List i krotek. Chociaż zestawy mają kolejność, to kolejność ta jest dowolne i nie pod kontrolą programisty. Druga różnica polega na tym, że elementy w zestawie muszą być unikalne.

set z definicji. [python | wiki].

>>> x = set([1, 1, 2, 2, 3, 3])
>>> x
{1, 2, 3}
 6
Author: user2601995,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-25 22:43:12

Set wygrane z powodu prawie natychmiastowych sprawdzeń "zawiera": https://en.wikipedia.org/wiki/Hash_table

List implementacja: Zwykle tablica, niski poziom blisko metalu, dobra do iteracji i losowego dostępu przez indeks elementu.

Set implementacja: https://en.wikipedia.org/wiki/Hash_table , nie iteruje na liście, ale znajduje element, obliczając hash z klucza, więc zależy to od Natury kluczowych elementów i funkcja hash. Podobne do tego, co stosuje się w przypadku dict. Podejrzewam, że {[1] } może być szybsze, jeśli masz bardzo mało elementów (set wykona sprawdzenie zawartości. Jest również szybki do dodawania i usuwania elementów.

Uwaga : Jeśli list jest już posortowane, wyszukiwanie list może być dość szybkie, ale dla zwykłych przypadków {[2] } jest szybsze i prostsze dla sprawdzania zawartości.

 3
Author: Christophe Roussy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-12 08:00:09

Polecam implementację Set, w której przypadek użycia ogranicza się do odwoływania się lub wyszukiwania istnienia oraz implementację krotki, w której przypadek użycia wymaga wykonania iteracji. Lista jest implementacją niskiego poziomu i wymaga znacznego nakładu pamięci.

 0
Author: Aditya Kumar Roy - Consultant,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-07 08:35:40