2010-12-31 14 views
0

Wenn ich eine Liste von Zahlen habe und wenn ich das gleiche Ding mit Wörterbuch implementiere, werden sie beide den gleichen Speicherplatz belegen?Python Speichergröße

Eg.

list = [[0,1],[1,0]] 
dict = {'0,0' = 0 , '0,1' = 1, '1,0' = 1, '1,1' = 0 } 

wird die Speichergröße von list und dict gleich sein? Welches wird mehr Platz einnehmen?

+1

Was versuchen Sie wirklich, und warum? –

+0

Das Wörterbuch wird offensichtlich größer sein, es hat mehr Elemente, ist eine komplexere Struktur usw. Es ist natürlich größer. Die Frage ist, warum willst du das wissen? –

Antwort

1

Es gibt sehr gute Chancen, dass das Wörterbuch größer wird.

Ein Wörterbuch und eine Liste sind beide ziemlich unterschiedliche Datenstrukturen. Wenn es um Speicher- und Prozessorbefehle geht, ist eine Liste relativ einfach: Alle Werte sind zusammenhängend, und wenn Sie auf Element n zugreifen möchten, gehen Sie am Anfang der Liste, verschieben n Elemente vorwärts und geben es zurück. Dies ist einfach, da Listenelemente zusammenhängend sind und ganzzahlige Schlüssel haben.

Auf der anderen Seite sind Einschränkungen für Wörterbücher ziemlich unterschiedlich. Sie können nicht einfach zum Anfang des Wörterbuchs gehen, das Element key vorwärts verschieben und zurückgeben, weil key möglicherweise nicht numerisch ist. Außerdem müssen Schlüssel nicht zusammenhängend sein.

Im Fall eines Wörterbuchs benötigen Sie eine Struktur, um die mit den Schlüsseln verbundenen Werte sehr einfach zu finden, auch wenn keine Beziehung zwischen ihnen besteht. Daher kann dieselbe Art von Algorithmen, die eine Liste verwendet, nicht verwendet werden. Und typischerweise sind die Datenstrukturen, die von Wörterbüchern benötigt werden, größer als für Listen benötigte Datenstrukturen.

Zufälligerweise können beide die gleiche Größe haben, obwohl es irgendwie überraschend wäre. Obwohl die Datenrepräsentation wird unterschiedlich sein, egal was.

3

Wenn Sie mit Python 2.6 oder höher, können Sie sys.getsizeof() verwenden, um einen Test

>>> import sys 
>>> aList = [[0,1],[1,0]] 
>>> aDict = {'0,0' : 0 , '0,1' : 1, '1,0' : 1, '1,1' : 0 } 
>>> sys.getsizeof(aList) 
44 
>>> sys.getsizeof(aDict) 
140 

Mit dem Beispiel zu tun, Sie zur Verfügung gestellt, sehen wir, dass aDict mehr Platz im Speicher in Anspruch nimmt.

+3

Beachten Sie, dass dies nicht wirklich sehr sinnvoll ist. Sie berechnen nicht die Größe der internen Listen. – aaronasterling

1

Das Ermitteln der Größe von Objekten in Python ist schwierig. Scheinbar kann dies mit sys.getsizeof getan werden, aber es gibt unvollständige Daten zurück.

Eine leere Liste hat eine Größe von 32 Bytes auf meinem System.

>>> sys.getsizeof([]) 
32 

Eine Liste mit einem Element hat eine Größe von 36 Bytes. Dies scheint nicht nach dem Element zu variieren.

>>> sys.getsizeof([[1, 2]]) 
36 
>>> sys.getsizeof([1]) 
36 

Also müssten Sie auch die Größe der inneren Liste wissen.

>>> sys.getsizeof([1, 2]) 
40 

So Ihre Speichernutzung für eine Liste (die gleichen wie mein System vorausgesetzt) ​​sollte für jede interne Liste 32 Byte plus 44 Byte sein. Dies liegt daran, dass Python den Overhead speichert, der mit dem Führen einer Liste verbunden ist, die 32 Bytes kostet. Jeder Zusatzeintrag wird als Zeiger auf das Objekt dargestellt und kostet 4 Bytes. So kostet der Zeiger 4 Bytes über was auch immer Sie speichern. Bei zwei Elementlisten sind dies 40 Byte.

Für ein dict, dann ist es 136 für ein leeres dict

>>> sys.getsizeof({}) 
136 

Von dort wird es seine Größe vervierfachen als Hinzufügen von Mitgliedern bewirkt, dass es aus dem Raum und Risiko häufig Hash-Kollisionen laufen. Auch hier müssen Sie die Größe des zu speichernden Objekts und die Schlüssel angeben.

>>> sys.getsizeof({1: 2}) 
136 
1

Kurz gesagt, werden sie nicht gleich sein. Die Liste sollte besser funktionieren, es sei denn, Sie können dünn besetzte Listen verwenden, die in einem Dict implementiert werden könnten.

Wie von mehreren anderen erwähnt, summiert getsizeof die enthaltenen Objekte nicht.

Hier ist ein Rezept, das für Sie auf Standard-Python (3.0) -Typen funktioniert.

Compute Memory footprint of an object and its contents

Mit diesem Rezept auf Python 3.1 sind hier einige Ergebnisse:

aList = [[x,x] for x in range(1000)] 
aListMod10 = [[x%10,x%10] for x in range(1000)] 
aTuple = [(x,x) for x in range(1000)] 
aDictString = dict(("%s,%s" % (x,x),x) for x in range(1000)) 
aDictTuple = dict(((x,x),x) for x in range(1000)) 

print("0", total_size(0)) 
print("10", total_size(10)) 
print("100", total_size(100)) 
print("1000", total_size(1000)) 

print("[0,1]", total_size([0,1])) 
print("(0,1)", total_size((0,1))) 

print("aList", total_size(aList)) 
print("aTuple", total_size(aTuple)) 
print("aListMod10", total_size(aListMod10)) 
print("aDictString", total_size(aDictString)) 
print("aDictTuple", total_size(aDictTuple)) 

print("[0]'s", total_size([0 for x in range(1000)])) 
print("[x%10]'s", total_size([x%10 for x in range(1000)])) 
print("[x%100]'s", total_size([x%100 for x in range(1000)])) 
print("[x]'s", total_size([x for x in range(1000)])) 

Ausgang:

0 12 
10 14 
100 14 
1000 14 

[0,1] 70 
(0,1) 62 

aList 62514 
aTuple 54514 
aListMod10 48654 
aDictString 82274 
aDictTuple 74714 

[0]'s 4528 
[x%10]'s 4654 
[x%100]'s 5914 
[x]'s 18514 

Es scheint logisch zu folgen, dass die leistungsstärksten Speicher Option sein würde Verwenden Sie 2 Listen:

list_x = [0, 1, ...] 
list_y = [1, 0, ...] 

Dies kann sich nur lohnen, wenn der Arbeitsspeicher knapp wird und Ihre Liste voraussichtlich groß sein wird. Ich würde vermuten, dass das Nutzungsmuster würde die Schaffung (x, y) -Tupeln alle über den Ort wie auch immer, es kann so sein, dass Sie sollten wirklich nur tun:

tuples = [(0, 1), (1, 0), ...] 

Alle Dinge gleich sind, wählen, was Ihnen erlaubt, schreibe den lesbarsten Code.

Verwandte Themen