Listen, dass große eine große Menge an Platz in Anspruch nehmen würde, da jedes Element in der Liste mindestens 4 Bytes besetzen würde, also nur eine Liste mit maximal erlaubten Elementen einnehmen würde mindestens 2 GB RAM . Und das ist ohne Berücksichtigung 64-Bit-Systeme .
4 * 5.4e+8 = 2.1e+9
, 2,1 GB
8 * 1.2e+18 = 9.2+18
, 9.2 EB (ja, Exabyte)
aus Gründen der Frage jedoch, nehmen wir an, dass Sie eine Menge RAM.
Eine der einfachsten Optionen wäre, ein eigenes Objekt zu erstellen, das die umfangreiche Liste enthält. Es würde im Grunde die riesige Liste in kleinere Listen aufteilen und dann bei Bedarf entsprechend darauf zugreifen. Da es no real benefits of subclassing list
gibt, weil Sie sowieso alle Methoden neu schreiben müssten, wäre es besser, nur object
zu unterklassifizieren und dann von dort zu gehen. Das einzige, was hier wichtig ist, ist, niemals die Unterlisten zu kombinieren oder zu kopieren (weil sie massiv sind), also verwenden Sie itertools.chain
, um die Listen bei Bedarf zu überfliegen. Hier
ist ein Beispiel für die einfachstenen Listen Methoden append
, extend
, get/setitem
Arbeits:
import sys
from itertools import chain
class largeList(object):
def __init__(self, mylist=[]):
self.maxSize = sys.maxsize/4
self.src = [[]]
self.extend(mylist)
def __iter__(self):
return chain(*self.src)
def __getitem__(self, idx):
return self.src[int(idx/self.maxSize)][idx%self.maxSize]
def __setitem__(self, idx, item):
self.src[int(idx/self.maxSize)][idx%self.maxSize] = item
# expand set/getitem to support negative indexing.
def append(self, item):
if len(self.src[-1]) < self.maxSize:
self.src[-1].append(item)
else:
self.src.append([item])
def extend(self, items):
remainder = self.maxSize - len(self.src[-1])
self.src[-1].extend(items[:remainder])
for i in xrange(0, len(items[remainder:]), self.maxSize):
self.src.append(items[remainder:][i:i+self.maxSize])
def __len__(self):
return sum(len(l) for l in self.src)
def __str__(self):
size = self.__len__()
if size >= 8:
first, last = [], []
for i, ele in enumerate(self.__iter__()):
if i < 3:
first.append(ele)
if i >= size - 3:
last.append(ele)
return str(first)[:-1] + ', ..., ' + str(last)[1:]
return str(list(self.__iter__()))
Beispiel für die Verwendung (, wenn Sie weniger als 4 GB freier RAM oder Sie sind auf einem 64-Bit-System ändern, sys.maxsize
vor diesem Versuch):
#sys.maxsize = 1000
list1 = largeList(xrange(sys.maxsize/4 + 2))
print len(list1)
# 53687093
print list1
#[0, 1, 2, ..., 536870910, 536870911, 536870912]
print list1.src
#[[0, 1, 2 ..., 536870910], [536870911, 536870912]]
list1.extend([42, 43])
print list1
#[0, 1, 2, ..., 536870912, 42, 43]
das Ergebnis: intern die Listen in mehrere Listen aufgeteilt werden, während sie erscheinen ju zu sein das erste bei der Arbeit mit ihnen. Weitere list
Funktionalitäten können einfach durch Hinzufügen weiterer Methoden hinzugefügt werden. Z.B. pop
, remove
, insert
und index
:
(...)
def pop(self, idx):
listidx = int(idx/self.maxSize)
itempopped = self.src[listidx].pop(idx%self.maxSize)
for i in xrange(listidx, len(self.src)-1):
self.src[i].append(self.src[i+1].pop(0))
if not self.src[-1]:
del self.src[-1]
return itempopped
def remove(self, item):
for i, ele in enumerate(self.__iter__()):
if ele == item:
self.pop(i)
break
def insert(self, idx, item):
listidx = int(idx/self.maxSize)
itemtoshift = self.src[listidx].pop(-1)
self.src[listidx].insert(idx%self.maxSize, item)
for i in xrange(listidx+1, len(self.src)-1):
itemremoved = self.src[i].pop(-1)
self.src[i].insert(0, itemtoshift)
itemtoshift = itemremoved
if len(self.src[-1]) < self.maxSize:
self.src[-1].insert(0, itemtoshift)
else:
self.src.append([self.src[-1].pop(-1)])
self.src[-2].insert(0, itemtoshift)
def index(self, item):
for i, ele in enumerate(self.__iter__()):
if ele == item:
return i
return -1
Beispiel für die Verwendung, Fortsetzung:
#sys.maxsize = 1000
list1 = largeList(xrange(sys.maxsize/4 + 2))
list1.insert(0, 'a')
print list1
#['a', 0, 1, ..., 536870910, 536870911, 536870912]
list1.pop(2)
#1
list1.remove(536870910)
print list1.index('a')
#0
print len(list1)
#536870911
print list1
#['a', 0, 2, ..., 536870909, 536870911, 536870912]
print list.src
#[['a', 0, 2, ..., 536870909, 536870911], [536870912]]
Nun, nein, das ist, was eine "maximale Größe" bedeutet. Sie können 'itertools.chain' ein Bündel von Stücken zusammen, denke ich, wenn Sie die Erinnerung haben. –
Haben Sie berücksichtigt, dass jedes Element einer Liste mindestens 4 Bytes belegt, also '4 * 536, 870, 912 = 2147483648'. Nun, das sind 2 GB RAM nur für die Liste. Wenn die Elemente nicht identisch sind, bin ich ziemlich sicher, dass Sie einen MemoryError-Weg bekommen werden, bevor Sie diese Größe erreichen. – Bakuriu
@bakuriu danke für das darauf hin. Ich habe einen MemoryError bekommen. :( –