2014-12-18 11 views
50

Vedo alcune incongruenze quando si utilizza sys.getsizeof in quelli che dovrebbero essere elenchi identici. (Python 2.7.5)Perché la creazione di un elenco da un elenco lo rende più grande?

>>> lst = [0,1,2,3,4,5,6,7,8,9] 
>>> sys.getsizeof(lst) 
76 
>>> lst2 = list(lst) 
>>> sys.getsizeof(lst2) 
104 
>>> lst3 = list(lst2) 
>>> sys.getsizeof(lst3) 
104 
>>> sys.getsizeof(lst[:]) 
76 
>>> sys.getsizeof(lst2[:]) 
76 

Qualcuno ha una spiegazione semplice?

+7

Ho un'ipotesi, supportata da nessuna evidenza: le liste allocano memoria extra prima del tempo, in modo che le future operazioni 'append' abbiano ammortizzato la complessità O (1). Forse la differenza di dimensioni è dovuta a diverse quantità di memoria allocata aggiuntiva. – Kevin

+0

@Kevin, probabilmente sei corretto usando 'lst2 = lst [:]' restituisce la stessa dimensione –

risposta

54

Con un letterale di lista, la macchina virtuale crea la lista con una lunghezza impostata. Quando si passa una sequenza al costruttore list(), gli elementi vengono aggiunti uno ad uno (tramite list.extend()) e, come tale, l'elenco viene ridimensionato quando appropriato. Dal momento che il resize operation sovrastampa per ammortizzare il costo, l'elenco finale sarà di solito più grande della lista di origine.

+0

Ora mi sento imbarazzato per non averlo capito da solo. Grazie! –

+0

puoi spiegare per favore quanto segue un po 'di più? * Poiché l'operazione di ridimensionamento viene eseguita in ordine generale per ammortizzare il costo, l'elenco finale sarà in genere più grande della lista di origini * grazie! – Kasramvd

+0

@Kasra: se aggiungi 3 spazi ma ne compili solo 1, la destinazione avrà 2 spazi in più rispetto alla sorgente. –

11

Quando si crea un elenco letterale, la dimensione riportata è la dimensione minima necessaria per contenere i dati. Puoi vedere questo perché la dimensione salta se aggiungi un singolo elemento. Tuttavia, quando si usa list per copiarlo, esso alloca uno spazio extra - ci vogliono alcuni accodamenti prima che si rialloca (nel tuo caso, sospetto che l'8a append lo farà - ha bisogno di altri 4 byte per elemento). C'è probabilmente una ragione per cui questi comportamenti di allocazione sono diversi, ma non sono sicuro di cosa potrebbe essere.

+1

Grazie per aver suggerito 'append' di ottenere una panoramica della struttura interna, è stato molto utile. –

Problemi correlati