पाइथन, एक सूची को एक निश्चित आकार के लिए मजबूर करता है


83

पायथन (3) में मैं एक सूची बनाना चाहता हूं जिसमें अंतिम 5 चर शामिल होंगे। यहाँ एक उदाहरण है:

>>>l = []
>>>l.append('apple')
>>>l.append('orange')
>>>l.append('grape')
>>>l.append('banana')
>>>l.append('mango')
>>>print(l)
['apple','orange','grape','banana','mango']
>>>l.append('kiwi')
>>>print(l)
['orange','grape','banana','mango','kiwi'] #only 5 items in list

तो, अजगर में, ऊपर दिखाए गए प्रदर्शन को प्राप्त करने का कोई तरीका है? चर को एक सूची होने की आवश्यकता नहीं है, मैंने इसे केवल एक उदाहरण के रूप में उपयोग किया है।

धन्यवाद!

जवाबों:


145

आप इसके बजाय एक अधिकतम निर्माता तर्क के साथ एक संग्रह का उपयोग करना चाहते हो सकता है :

>>>l = collections.deque(maxlen=5)
>>>l.append('apple')
>>>l.append('orange')
>>>l.append('grape')
>>>l.append('banana')
>>>l.append('mango')
>>>print(l)
deque(['apple','orange','grape','banana','mango'], maxlen=5)
>>>l.append('kiwi')
>>>print(l)
deque(['orange','grape','banana','mango','kiwi'], maxlen=5) #only 5 items in list

+1, अच्छा - मैं उप-सूची बनाने का सुझाव देने वाला था ala gnibbler लेकिन मुझे संदेह था कि कोई पूर्व-निर्मित समाधान हो सकता है।
प्रेषित

अजगर ने समाधान कैसे लागू किया? जब नया तत्व जोड़ा जाता है तो क्या बायाँ तत्व बाहर छोड़ता है?
जिओ x

पायथन में बहुत सारी सूची-डेटा संरचनाएं हैं जो सूची में बदल सकती हैं जब आपको सूची () का उपयोग करके उनकी आवश्यकता होती है। उदाहरण के लिए, एक तानाशाही और कोशिश करें सूची (MyDict)।
माइकल डिलन

1
@ जिओ यह एक डबल एंडेड कतार है जिसका मतलब है कि आप कुशलतापूर्वक दोनों को जोड़ सकते हैं। वास्तव में वहाँ एक एपेंडलेफ्ट विधि है जो कि सामने वाले के सामने झुकना है। यदि एक अधिकतमलेन मौजूद है और दूसरे छोर से एक आइटम को हटा दिया जाएगा।
लैंबाकॉक

1
कृपया ध्यान दें कि यह समाधान बड़ी मात्रा की प्रतियों के लिए धीमा है, क्योंकि यह एक साधारण लिंक के विपरीत एक दोगुनी लिंक की गई सूची है, listजो कि ऐक एरे है।
गुलजार

14

मैं इसी मुद्दे में भाग गया ... एक्सेस स्पीड / विश्वसनीयता के मुद्दों के कारण मैक्स से = 5 डीकेन एक समर्थित विकल्प नहीं था।

सरल समाधान:

l = []
l.append(x)                         # add 'x' to right side of list
l = l[-5:]                          # maxlen=5

आपके द्वारा अपील करने के बाद, बस 'l' को 'l' के सबसे हाल के पांच तत्वों के रूप में फिर से परिभाषित करें।

print(l)

इसे फोन किया।

आपके उद्देश्यों के लिए आप वहीं रुक सकते थे ... लेकिन मुझे एक पॉपलेफ्ट () की आवश्यकता थी। जबकि पॉप () उस आइटम को दाईं ओर से हटाता है जहां इसे जोड़ा गया था ... पॉप (0) इसे बाईं ओर से हटाता है:

if len(l) == 5:                     # if the length of list 'l' has reached 5 
    right_in_left_out = l.pop(0)    # l.popleft()
else:                               #
    right_in_left_out = None        # return 'None' if not fully populated

जेम्स को Tradewave.net पर टिप दें

वर्ग कार्यों या छल के लिए कोई ज़रूरत नहीं है।

इसके अलावा ... बाएँ और दाएँ दाएँ जोड़ने के लिए:

l = []
l.insert(0, x)                      # l.appendleft(x)
l = l[-5:]                          # maxlen=5

क्या आपका अपेंडेलफ़्ट () समतुल्य होना चाहिए, क्या आप बिना डीके का उपयोग किए अपनी सूची को लोड करना चाहते हैं

अंत में, यदि आप बाईं ओर से एपेंड करना चुनते हैं ...

if len(l) == 5:                     # if the length of list 'l' has reached 5 
    left_in_right_out = l.pop()     # pop() from right side
else:                               #
    left_in_right_out = None        # return 'None' if not fully populated

14

आप उपवर्ग कर सकते हैं list

>>> class L(list):
...     def append(self, item):
...         list.append(self, item)
...         if len(self) > 5: del self[0]
... 
>>> l = L()
>>> l.append('apple')
>>> l.append('orange')
>>> l.append('grape')
>>> l.append('banana')
>>> l.append('mango')
>>> print(l)
['apple', 'orange', 'grape', 'banana', 'mango']
>>> l.append('kiwi')
>>> print(l)
['orange', 'grape', 'banana', 'mango', 'kiwi']
>>> 

2
इसके लिए आपको और विस्तार करने की आवश्यकता होगी insert, extendऔर इसके लिए setitemतरीके ( l[1:1] = range(100)) मूर्खतापूर्ण होने चाहिए।
लॉरिट्ज वी। थुलो

1
विचार करें del self[0]
अल्फ

1
और शायद __add__यह भी ओवरराइड करने की आवश्यकता है
ली

7

dequeयादृच्छिक पहुँच के लिए धीमा है और स्लाइसिंग का समर्थन नहीं करता है। Gnibbler के सुझाव पर चलते हुए, मैंने एक पूरा listउपवर्ग तैयार किया।

हालाँकि, इसे केवल दाएँ-से-बाएँ "रोल" करने के लिए डिज़ाइन किया गया है। उदाहरण के लिए, insert()"पूर्ण" सूची पर कोई प्रभाव नहीं पड़ेगा।

class LimitedList(list):

    # Read-only
    @property
    def maxLen(self):
        return self._maxLen

    def __init__(self, *args, **kwargs):
        self._maxLen = kwargs.pop("maxLen")
        list.__init__(self, *args, **kwargs)

    def _truncate(self):
        """Called by various methods to reinforce the maximum length."""
        dif = len(self)-self._maxLen
        if dif > 0:
            self[:dif]=[]

    def append(self, x):
        list.append(self, x)
        self._truncate()

    def insert(self, *args):
        list.insert(self, *args)
        self._truncate()

    def extend(self, x):
        list.extend(self, x)
        self._truncate()

    def __setitem__(self, *args):
        list.__setitem__(self, *args)
        self._truncate()

    def __setslice__(self, *args):
        list.__setslice__(self, *args)
        self._truncate()

1

आप PyMongo में कैप्ड संग्रह का उपयोग कर सकते हैं - यह ओवरकिल है, लेकिन यह अच्छी तरह से काम करता है:

import pymongo

#create collection
db.createCollection("my_capped_list",{capped:True, max:5})

#do inserts ...

#Read list
l = list(db.my_capped_list.find())

इसलिए जब भी आप कॉल my_capped_listकरेंगे, आप सम्मिलित किए गए अंतिम 5 तत्वों को पुनः प्राप्त करेंगे।


0

सबसे अधिक बार जब आपको इस तरह की सुविधा की आवश्यकता होती है, तो आप एक फ़ंक्शन लिखते हैं जो सूची लेता है और फिर अंतिम पांच तत्वों को वापस करता है।

>>> l = range(10)
>>> l[-5:]

लेकिन अगर आप वास्तव में एक कस्टम सूची चाहते हैं, तो पांच तत्वों पर एक कैप होने पर, आप अंतर्निहित सूची को ओवरराइड कर सकते हैं और यह विधियां हैं, आप कुछ इस तरह से करेंगे, यह सभी तरीकों के लिए है।

class fivelist(list):
    def __init__(self, items):
        list.__init__(self, items[-5:])

    def insert(self, i, x):
        list.insert(self, i, x)
        return self[-5:]

    def __getitem__(self, i):
        if i > 4:
           raise IndexError
        return list.__getitem__(self, i)

    def __setitem__(self, i, x):
        if 0<= i <= 4:
          return list.__setitem__(self, i, x)
        else:
          raise IndexError

इस कारण से कि मैं किसी ऐसे फ़ंक्शन का उपयोग नहीं कर सकता हूं जो सूची का हिस्सा देता है, क्योंकि सूची समय के साथ बहुत बड़ी हो जाएगी, और यह बहुत सारे बेकार डेटा पकड़ेगी जो फिर कभी उपयोग नहीं किए जाएंगे।
लनरेट

जिसे फिर से फंक्शन द्वारा नियंत्रित किया जा सकता है। यदि बड़े हो जाते हैं, तो शुरुआत में ही शेड करें।
सेंथिल कुमारन

returnमें insert()क्योंकि, व्यर्थ है list.insertयथा-स्थान संचालित करने के लिए करना है।
11

-3

यह नीचे दिए गए समाधान के रूप में सरल हो सकता है

lst = []
arr_size = int(input("Enter the array size "))
while len(lst) != arr_size:
    arr_elem= int(input("Enter the array element "))
    lst.append(arr_elem)

sum_of_elements = sum(lst)

print("Sum is {0}".format(sum_of_elements))
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.