Python,强制列表固定大小

lan*_*rat 67 python list

在Python(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
Run Code Online (Sandbox Code Playgroud)

那么,在python中,有没有办法实现上面演示的内容?变量不需要是一个列表,我只是用它作为例子.

谢谢!

lam*_*cck 121

您可能希望使用具有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)
deque(['orange','grape','banana','mango','kiwi'], maxlen=5) #only 5 items in list
Run Code Online (Sandbox Code Playgroud)

  • @xiao,它是一个双端队列,这意味着您可以有效地添加到任一端。事实上有一个appendleft方法可以追加到双端队列的前面。如果存在 maxlen,并且append/appendleft 将超过一项,则从另一端删除一项。 (2认同)
  • print(list(l)) 只会打印内容 (2认同)

Joh*_*ooy 12

你可以继承 list

>>> class L(list):
...     def append(self, item):
...         list.append(self, item)
...         if len(self) > 5: self[:1]=[]
... 
>>> 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']
>>> 
Run Code Online (Sandbox Code Playgroud)

  • 您还需要扩展insert,extend和setitem方法(l [1:1] = range(100)),以使其万无一失。 (2认同)
  • 也许还需要覆盖`__add__` (2认同)

lit*_*nce 11

我遇到了同样的问题......由于访问速度/可靠性问题,来自deque的maxlen = 5不是受支持的选项.

简单的解决方案:

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

追加后,只需将'l'重新定义为'l'的最新五个元素.

print(l)
Run Code Online (Sandbox Code Playgroud)

称之为完成.

为了你的目的,你可以在那里停止......但我需要一个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
Run Code Online (Sandbox Code Playgroud)

在Tradewave.net向James提示

不需要类功能或双端功能.

进一步......左右追加:

l = []
l.insert(0, x)                      # l.appendleft(x)
l = l[-5:]                          # maxlen=5
Run Code Online (Sandbox Code Playgroud)

如果你想在不使用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
Run Code Online (Sandbox Code Playgroud)


小智 5

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()
Run Code Online (Sandbox Code Playgroud)