Python 如何将列表强制设置为固定大小?

Python 如何将列表强制设置为固定大小?,python,list,Python,List,在Python3中,我想创建一个包含最后5个变量的列表 以下是一个例子: >>>l = [] >>>l.append('apple') >>>l.append('orange') >>>l.append('grape') >>>l.append('banana') >>>l.append('mango') >>>print(l) ['apple','orange','gr

在Python3中,我想创建一个包含最后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
那么,在python中,是否有任何方法可以实现上面演示的内容?变量不需要是列表,我只是将其用作示例。

您可能希望使用带有maxlen构造函数参数的对象:

>>>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

您可以子类化
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']
>>> 

通常,当您需要这样一种功能时,您会编写一个函数,该函数获取列表,然后返回最后五个元素

>>> 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
class五级列表(列表):
定义初始化(自身,项目):
列表。\uuuu初始化(self,items[-5:])
def插件(自身、i、x):
列表.插入(self,i,x)
返回自我[-5:]
定义获取项目(自我,i):
如果i>4:
提升索引器
返回列表。获取项目(self,i)
定义设置项(self,i,x):

如果0
deque
对于随机访问速度较慢,并且不支持切片。根据gnibbler的建议,我创建了一个完整的
列表
子类

但是,它的设计只是从右向左“滚动”。例如,“完整”列表上的
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()

我遇到了同样的问题。。。由于访问速度/可靠性问题,deque的maxlen=5不受支持

简单解决方案:

l = []
l.append(x)                         # add 'x' to right side of list
l = l[-5:]                          # maxlen=5
附加后,只需将“l”重新定义为“l”的最新五个元素

print(l)
到此为止

为了你的目的,你可以停在那里。。。但我需要一个左撇子()。而pop()则从刚附加的项目的右侧删除该项目。。。pop(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网站上给詹姆斯的帽子小费

不需要类函数或deque

进一步。。。要向左追加并向右弹出,请执行以下操作:

l = []
l.insert(0, x)                      # l.appendleft(x)
l = l[-5:]                          # maxlen=5
如果您希望在不使用deque的情况下预先加载列表,则将是您的appendleft()等效项

最后,如果您选择从左侧追加

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

它可以像下面的解决方案一样简单

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))

你可以在PyMongo中使用一个capped集合-这有点过分,但它做得很好:

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个元素。

+1,很好--我正要建议将list ala子类化,但我怀疑可能存在预构建的解决方案。python如何实现该解决方案?添加新元素时,deque是否会弹出左边的元素?Python有很多列表数据结构,当您需要时,可以使用list()将它们转换为列表。例如,制作一个dict和试用列表(MyDict)。@xiao它是一个双端队列,这意味着您可以有效地添加到任意一端。事实上,有一个appendleft方法可以附加到deque的前面。如果存在maxlen,并且append/appendleft将跳过另一端的一个项目。请注意,此解决方案对于大数据块的副本速度较慢,因为它是一个双链接列表,与简单的
列表
相反,它是一个c数组。我不能使用返回部分列表的函数的原因是,随着时间的推移,列表将变得非常大,并且它将保存大量无用的数据,这些数据将不再被使用。这可以再次由函数控制。如果变量变大,则在开始时去掉这些变量。
insert()
中的
return
是没有意义的,因为
list.insert
旨在就地操作。您还需要扩展
insert
extend
setitem
方法(
l[1:1]=range(100)
)这是万无一失的。请考虑<代码>德尔自己[ 0 ] < /代码>。