如何在添加新元素时自动限制列表的长度?

问题描述 投票:0回答:7

我想创建一个列表,其中包含最后输入的 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)  # only 5 items in list
['orange', 'grape', 'banana', 'mango', 'kiwi']

那么,在Python中,有什么方法可以实现上面演示的功能吗?该变量不需要是一个列表,我只是用它作为例子。

python list
7个回答
173
投票

您可能想使用带有 maxlen 构造函数参数的

collections.deque
对象:

>>> 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)  # only 5 items in list
deque(['orange', 'grape', 'banana', 'mango', 'kiwi'], maxlen=5)

17
投票

我遇到了同样的问题...由于访问速度/可靠性问题,双端队列中的 maxlen=5 不是受支持的选项。

简单的解决方案:

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

追加后,只需将“l”重新定义为“l”的最新五个元素即可。

print(l)

就这样吧。

为了你的目的,你可以停在那里......但我需要一个 popleft()。而 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 的 James 致敬

不需要类函数或双端队列。

进一步...向左追加并向右弹出:

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

如果您想在不使用双端队列的情况下前端加载列表,则相当于您的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

15
投票

你可以子类化

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

9
投票

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

-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))
© www.soinside.com 2019 - 2024. All rights reserved.