In Python, quale struttura di dati è più efficiente / veloce? Supponendo che l'ordine non sia importante per me e controllerei comunque i duplicati, un Python è più lento di un elenco Python?
In Python, quale struttura di dati è più efficiente / veloce? Supponendo che l'ordine non sia importante per me e controllerei comunque i duplicati, un Python è più lento di un elenco Python?
Risposte:
Dipende da cosa hai intenzione di farne.
Gli insiemi sono significativamente più veloci quando si tratta di determinare se un oggetto è presente nell'insieme (come in x in s
), ma sono più lenti degli elenchi quando si tratta di iterare sul loro contenuto.
Puoi usare il modulo timeit per vedere quale è più veloce per la tua situazione.
Gli elenchi sono leggermente più veloci degli insiemi quando si desidera semplicemente scorrere i valori.
Gli insiemi, tuttavia, sono significativamente più veloci degli elenchi se si desidera verificare se un elemento è contenuto al suo interno. Tuttavia possono contenere solo oggetti unici.
Si scopre che le tuple si comportano quasi nello stesso modo delle liste, tranne per la loro immutabilità.
iterazione
>>> 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
Determina se è presente un oggetto
>>> 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
Elenco delle prestazioni:
>>> import timeit
>>> timeit.timeit(stmt='10**6 in a', setup='a = range(10**6)', number=100000)
0.008128150348026608
Imposta le prestazioni:
>>> timeit.timeit(stmt='10**6 in a', setup='a = set(range(10**6))', number=100000)
0.005674857488571661
Potresti considerare le Tuple come simili agli elenchi ma non modificabili. Occupano un po 'meno memoria e sono più veloci ad accedervi. Non sono così flessibili ma sono più efficienti delle liste. Il loro uso normale è di servire come chiavi del dizionario.
Gli insiemi sono anche strutture sequenziali ma con due differenze rispetto a liste e tuple. Sebbene gli insiemi abbiano un ordine, quell'ordine è arbitrario e non sotto il controllo del programmatore. La seconda differenza è che gli elementi in un set devono essere unici.
set
per definizione. [ pitone | wiki ].
>>> x = set([1, 1, 2, 2, 3, 3])
>>> x
{1, 2, 3}
set
collegamento del tipo incorporato ( docs.python.org/2/library/stdtypes.html#set ) non alla sets
libreria obsoleta . In secondo luogo, "I set sono anche strutture di sequenza", leggi quanto segue dal link di tipo incorporato: "Essendo una raccolta non ordinata, i set non registrano la posizione dell'elemento o l'ordine di inserimento. Di conseguenza, i set non supportano indicizzazione, divisione o altro comportamento simile a una sequenza ".
range
non lo è list
. range
è una classe speciale con __contains__
metodo magico personalizzato .
xrange
)
Set
vince a causa di controlli "contiene" quasi istantanei: https://en.wikipedia.org/wiki/Hash_table
Implementazione elenco : di solito un array, basso livello vicino al metal, buono per iterazione e accesso casuale per indice elemento.
Imposta implementazione: https://en.wikipedia.org/wiki/Hash_table , non scorre su un elenco, ma trova l'elemento calcolando un hash dalla chiave, quindi dipende dalla natura degli elementi chiave e dall'hash funzione. Simile a ciò che viene utilizzato per dict. Sospetto che list
potrebbe essere più veloce se hai pochissimi elementi (<5), maggiore è il numero di elementi, migliore set
sarà il rendimento per un controllo del contenuto. È inoltre veloce per l'aggiunta e la rimozione di elementi. Inoltre, tieni sempre presente che la costruzione di un set ha un costo!
NOTA : se l' list
opzione è già ordinata, la ricerca list
potrebbe essere abbastanza veloce, ma nei casi normali a set
è più veloce e più semplice per contenere i controlli.
Le strutture dati (DS) sono importanti perché vengono utilizzate per eseguire operazioni sui dati che implicano sostanzialmente: prendere un input , elaborarlo e restituire l'output .
Alcune strutture di dati sono più utili di altre in alcuni casi particolari. Pertanto, è abbastanza ingiusto chiedere quale (DS) sia più efficiente / veloce. È come chiedere quale strumento sia più efficiente tra un coltello e una forchetta. Voglio dire, tutto dipende dalla situazione.
Un elenco è una sequenza mutabile , generalmente utilizzata per archiviare raccolte di elementi omogenei .
Un oggetto set è una raccolta non ordinata di oggetti hash distinti . È comunemente usato per testare l'appartenenza, rimuovere i duplicati da una sequenza e calcolare operazioni matematiche come intersezione, unione, differenza e differenza simmetrica.
Da alcune delle risposte, è chiaro che un elenco è molto più veloce di un set quando scorre i valori. D'altra parte, un set è più veloce di un elenco quando si verifica se un elemento è contenuto al suo interno. Pertanto, l'unica cosa che puoi dire è che un elenco è meglio di un set per alcune operazioni particolari e viceversa.
Ero interessato ai risultati quando controllavo, con CPython, se un valore è uno di un piccolo numero di letterali. set
vince in Python 3 vs tuple
, list
e 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))
Produzione:
tuple
4.735646052286029
list
4.7308746771886945
set
3.5755991376936436
or
4.687681658193469
Da 3 a 5 letterali, set
vince ancora con un ampio margine e or
diventa il più lento.
In Python 2, set
è sempre il più lento. or
è il più veloce da 2 a 3 letterali tuple
e list
sono più veloci con 4 o più letterali. Non riuscivo a distinguere la velocità del tuple
vs list
.
Quando i valori da testare venivano memorizzati nella cache in una variabile globale fuori dalla funzione, anziché creare il valore letterale all'interno del loop, set
vinceva ogni volta, anche in Python 2.
Questi risultati si applicano a CPython a 64 bit su un Core i7.
Vorrei raccomandare un'implementazione Set in cui il caso d'uso è limitato al riferimento o cercare l'esistenza e l'implementazione Tuple in cui il caso d'uso richiede l'esecuzione dell'iterazione. Un elenco è un'implementazione di basso livello e richiede un notevole sovraccarico di memoria.
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)
Output dopo aver confrontato 10 iterazioni per tutti e 3: confronto
Gli insiemi sono più veloci, più ottieni più funzioni con gli insiemi, ad esempio diciamo che hai due insiemi:
set1 = {"Harry Potter", "James Bond", "Iron Man"}
set2 = {"Captain America", "Black Widow", "Hulk", "Harry Potter", "James Bond"}
Possiamo facilmente unire due set:
set3 = set1.union(set2)
Scopri cosa è comune in entrambi:
set3 = set1.intersection(set2)
Scopri cosa c'è di diverso in entrambi:
set3 = set1.difference(set2)
E altro ancora! Provali, sono divertenti! Inoltre, se devi lavorare su valori diversi in 2 elenchi o valori comuni in 2 elenchi, preferisco convertire i tuoi elenchi in set e molti programmatori lo fanno in questo modo. Spero che ti aiuti :-)