ProgramingTip

Python, 목록을 고정 크기로 강제

bestdevel 2020. 11. 20. 09:17
반응형

Python, 목록을 고정 크기로 강제


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

그래서, 여기서 위에서는 달성하는 방법이 있습니까? 변수는 목록이 아니어도 종료로 사용했습니다.

감사합니다!


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

당신은 하위 클래스를 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']
>>> 

이 같은 문제가 발생했습니다 ... deque의 maxlen = 5는 액세스 속도 / 신뢰성 문제로 인해 지원되는 옵션이 아닙니다.

간단한 솔루션 :

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

추가 한 후 'l'을 'l'의 가장 최근 5 개 요소로 재정의하십시오.

print(l)

Done이라고 부 사용.

당신의 목적을 위해 당신은 바로 거기에서 멈출 수 있습니다 ... 나는 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

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

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

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 개 요소를 검색합니다.


이러한 종류의 기능이 필요할 때 대부분의 경우 목록을 가져온 다음 마지막 5 개 요소를 반환하는 함수를 작성합니다.

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

그러나 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

아래 솔루션처럼 간단 할 수 있습니다.

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

참고 URL : https://stackoverflow.com/questions/5944708/python-forcing-a-list-to-a-fixed-size

반응형