पाइथन
उत्तर
सूचियाँ कि बड़े ऊपर अंतरिक्ष के एक बड़े पैमाने पर राशि, अधिकतम स्वीकृत तत्वों के साथ तो बस एक सूची ले जाएगा के रूप में सूची में प्रत्येक तत्व कम से कम 4 बाइट्स का स्थान लेगा, ऊपर ले जाएगा न्यूनतम 2 जीबी रैम । और यह 64-बिट सिस्टम पर विचार किए बिना भी है।
4 * 5.4e+8 = 2.1e+9
, 2.1 जीबी8 * 1.2e+18 = 9.2+18
, 9.2 ईबी (हाँ, एक्साबाइट)
हालांकि, प्रश्न के लिए, मान लें कि आप राम का एक बहुत है कि करते हैं।
सबसे आसान विकल्पों में से एक है विशाल सूची को पकड़ने और संभालने के लिए आपको अपना ऑब्जेक्ट बनाना होगा। यह मूल रूप से बड़ी सूची में छोटी सूची में विभाजित होगा, और फिर आवश्यकता होने पर तदनुसार उन्हें एक्सेस करेगा। चूंकि no real benefits of subclassing list
हैं क्योंकि आपको वैसे भी सभी विधियों को फिर से लिखना होगा, आप object
को उप-वर्गीकृत करने के बेहतर होंगे और फिर वहां से जाएं। यहां केवल एक चीज है जो उप-सूचियों को कभी गठबंधन या प्रतिलिपि नहीं करना है (क्योंकि वे बड़े पैमाने पर हैं), इसलिए आवश्यक होने पर सूचियों पर लूप के लिए itertools.chain
का उपयोग करें।
यहाँ सबसे सरल सूची-तरीकों का एक उदाहरण है append
, extend
, get/setitem
काम कर रहे:
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__()))
उदाहरण का उपयोग करें (आप से 4 जीबी मुक्त रैम कम है या आप एक 64-बिट सिस्टम पर कर रहे हैं , इस प्रयास करने से पहले sys.maxsize
बदलने):
#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]
परिणाम: आंतरिक रूप से सूची, एकाधिक सूचियों में विभाजित हैं, जबकि वे जू प्रतीत उनके साथ काम करते समय सेंट एक। अधिक 0 जोड़कर अधिक list
कार्यक्षमताओं को आसानी से जोड़ा जा सकता है। जैसे pop
, remove
, insert
, और 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
उदाहरण उपयोग करते हैं, जारी रखा:
#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]]
ठीक है, नहीं, कि क्या एक "अधिकतम आकार" का अर्थ है। यदि आप स्मृति रखते हैं, तो आप अनुमान लगा सकते हैं कि आप एक साथ समूह का एक गुच्छा 'itertools.chain' कर सकते हैं। –
क्या आपने ध्यान दिया कि सूची के प्रत्येक तत्व, कम से कम, 4 बाइट्स पर कब्जा करते हैं, इस प्रकार '4 * 536,870,912 = 2147483648'। अब सूची के लिए 2 जीबी रैम है। यदि तत्व समान नहीं हैं तो मुझे पूरा यकीन है कि आपको उस आकार तक पहुंचने से पहले मेमोरी त्रुटि मिल जाएगी। – Bakuriu
@bakuriu आपको इंगित करने के लिए धन्यवाद। मुझे एक मेमोरी एरर मिला। :( –