Risposte:
È un array dinamico . Prova pratica: l'indicizzazione prende (ovviamente con differenze estremamente piccole (0,0013 µsec!)) Allo stesso tempo, indipendentemente dall'indice:
...>python -m timeit --setup="x = [None]*1000" "x[500]"
10000000 loops, best of 3: 0.0579 usec per loop
...>python -m timeit --setup="x = [None]*1000" "x[0]"
10000000 loops, best of 3: 0.0566 usec per loop
Sarei sbalordito se IronPython o Jython usassero elenchi collegati - rovinerebbero le prestazioni di molte molte librerie ampiamente utilizzate basate sul presupposto che gli elenchi siano array dinamici.
x=[None]*1000
, lasciando imprecisa la misurazione di ogni possibile differenza di accesso all'elenco. Devi separare l'inizializzazione:-s "x=[None]*100" "x[0]"
Il codice C è piuttosto semplice, in realtà. Espandendo una macro e potando alcuni commenti irrilevanti, si trova la struttura di base listobject.h
, che definisce un elenco come:
typedef struct {
PyObject_HEAD
Py_ssize_t ob_size;
/* Vector of pointers to list elements. list[0] is ob_item[0], etc. */
PyObject **ob_item;
/* ob_item contains space for 'allocated' elements. The number
* currently in use is ob_size.
* Invariants:
* 0 <= ob_size <= allocated
* len(list) == ob_size
* ob_item == NULL implies ob_size == allocated == 0
*/
Py_ssize_t allocated;
} PyListObject;
PyObject_HEAD
contiene un conteggio di riferimento e un identificatore di tipo. Quindi, è un vettore / array che si sovralloca. Il codice per ridimensionare un tale array quando è pieno è dentro listobject.c
. In realtà non raddoppia l'array, ma cresce allocando
new_allocated = (newsize >> 3) + (newsize < 9 ? 3 : 6);
new_allocated += newsize;
alla capacità ogni volta, dov'è newsize
la dimensione richiesta (non necessariamente allocated + 1
perché è possibile extend
tramite un numero arbitrario di elementi invece di append
'ordinarli uno per uno).
Vedi anche le FAQ di Python .
array
è preferibile il modulo o NumPy.
Questo dipende dall'implementazione, ma IIRC:
ArrayList
Quindi tutti hanno O (1) accesso casuale.
O(1)
indicizzazione delle liste è un presupposto piuttosto comune e valido, nessuna implementazione oserebbe romperla.
Suggerirei l'articolo di Laurent Luce "Implementazione dell'elenco Python" . È stato davvero utile per me perché l'autore spiega come l'elenco è implementato in CPython e utilizza diagrammi eccellenti per questo scopo.
Elencare la struttura dell'oggetto C.
Un oggetto elenco in CPython è rappresentato dalla seguente struttura C.
ob_item
è un elenco di puntatori agli elementi dell'elenco. allocato è il numero di slot allocati in memoria.typedef struct { PyObject_VAR_HEAD PyObject **ob_item; Py_ssize_t allocated; } PyListObject;
È importante notare la differenza tra gli slot allocati e le dimensioni dell'elenco. La dimensione di un elenco è la stessa di
len(l)
. Il numero di slot allocati è ciò che è stato allocato in memoria. Spesso vedrai che l'allocazione può essere maggiore della dimensione. Questo per evitare di dover chiamarerealloc
ogni volta che un nuovo elemento viene aggiunto all'elenco.
...
Aggiungere
Noi aggiungiamo un intero alla lista:
l.append(1)
. Che succede?
Continuiamo con l'aggiunta di un elemento in più:
l.append(2)
.list_resize
viene chiamato con n + 1 = 2 ma poiché la dimensione allocata è 4, non è necessario allocare più memoria. La stessa cosa succede quando aggiungiamo altri 2 numeri interi:l.append(3)
,l.append(4)
. Il diagramma seguente mostra ciò che abbiamo finora.
...
Inserire
Inseriamo un nuovo numero intero (5) in posizione 1:
l.insert(1,5)
e osserviamo cosa succede internamente.
...
Pop
Quando si pop l'ultimo elemento:
l.pop()
,listpop()
si chiama.list_resize
viene chiamato all'internolistpop()
e se la nuova dimensione è inferiore alla metà della dimensione allocata, l'elenco viene ridotto.Puoi osservare che lo slot 4 punta ancora all'intero ma l'importante è la dimensione della lista che è ora 4. Facciamo scoppiare un altro elemento. In
list_resize()
, size - 1 = 4 - 1 = 3 è inferiore alla metà degli slot allocati, quindi l'elenco viene ridotto a 6 slot e la nuova dimensione dell'elenco ora è 3.Puoi osservare che gli slot 3 e 4 puntano ancora ad alcuni numeri interi ma l'importante è la dimensione della lista che ora è 3.
...
Cancella lista Python oggetto ha un metodo per rimuovere un elemento specifico:
l.remove(5)
.
aggregation
, non composition
. Vorrei che ci fosse anche un elenco di composizione.
Secondo la documentazione ,
Gli elenchi di Python sono in realtà matrici di lunghezza variabile, non elenchi collegati in stile Lisp.
Come altri hanno già detto in precedenza, gli elenchi (quando apprezzabilmente grandi) vengono implementati allocando una quantità fissa di spazio e, se tale spazio deve riempire, allocando una quantità maggiore di spazio e copiando gli elementi.
Per capire perché il metodo è O (1) ammortizzato, senza perdita di generalità, supponiamo di aver inserito a = 2 ^ n elementi e che ora dobbiamo raddoppiare la nostra tabella a 2 ^ (n + 1) dimensione. Ciò significa che attualmente stiamo eseguendo 2 ^ (n + 1) operazioni. Ultima copia, abbiamo eseguito 2 ^ n operazioni. Prima abbiamo fatto 2 ^ (n-1) ... fino a 8,4,2,1. Ora, se sommiamo questi, otteniamo 1 + 2 + 4 + 8 + ... + 2 ^ (n + 1) = 2 ^ (n + 2) - 1 <4 * 2 ^ n = O (2 ^ n) = O (a) inserzioni totali (ovvero O (1) tempo ammortizzato). Inoltre, va notato che se la tabella consente di eliminare la riduzione della tabella deve essere eseguita con un fattore diverso (ad es. 3x)
Un elenco in Python è qualcosa di simile a un array, in cui è possibile memorizzare più valori. L'elenco è modificabile, il che significa che è possibile modificarlo. La cosa più importante che dovresti sapere, quando creiamo un elenco, Python crea automaticamente un riferimento_id per quella variabile di elenco. Se lo si modifica assegnando altre variabili, l'elenco principale verrà modificato. Proviamo con un esempio:
list_one = [1,2,3,4]
my_list = list_one
#my_list: [1,2,3,4]
my_list.append("new")
#my_list: [1,2,3,4,'new']
#list_one: [1,2,3,4,'new']
Aggiungiamo my_list
ma il nostro elenco principale è cambiato. L'elenco di quella media non è stato assegnato come un elenco di copie assegnato come riferimento.