Any way to track last 5 data points in python

So, I have an array containing several numbers. As my script works, more and more numbers are added to this array. However, I am not interested in all the numbers, but just want to keep track of the last 5 numbers.

I am currently just storing all the numbers in an array. However, this array is getting really big, and it is filled with unnecessary information.

I was thinking of creating a function that, when it adds an element to an array, also deletes the last element if the array already contains 5 numbers.

I also thought about creating a new class to create a data structure that does what I want. However, I only need to reference this array sometimes and this is just a small part of the script. Therefore, I believe that it is too difficult if I create a new class for this.

What is the best way to do this?

+7
python
source share
5 answers

Try using deque: http://docs.python.org/library/collections.html#deque-objects

"If maxlen is not specified or None, then deques can grow to an arbitrary length. Otherwise, deque is limited to the specified maximum length. After the division of a limited length is filled, when new items are added, the corresponding number of elements are discarded from the opposite end. Restrictions to limited lengths provide functionality similar to the tail filter on Unix, and are also useful for tracking transactions and other data pools in which only the most recent activity is of interest. "

+11
source share

I completely agree with the idea of ​​using Python with a limited length deque , if it is available, and if not, then Michael Anderson's simple solution is quite adequate. (I saved both). But I just wanted to mention the third option of the ring buffer, which is often used for such tasks when low memory and high speed are important. (In other words, in situations where you probably aren't using Python: -p) For example, the Linux kernel uses this structure to store log messages generated during the boot process until the system logger starts.

A Python implementation might look like this:

 class RingBuffer(object): def __init__(self, n): self._buf = [None] * n self._index = 0 self._valid = 0 def add(self, obj): n = len(self._buf) self._buf[self._index] = obj self._index += 1 if self._index == n self._index = 0 if self._valid < n: self._valid += 1 def __len__(self): return self._valid # could include other methods for accessing or modifying the contents 

Basically, what he does is pre-allocate an array (in Python, a list) of the desired length and fill it with dummy values. The buffer also contains an β€œindex” that indicates the next spot in the list to be filled with a value. Each time a value is added, it is stored in this place, and the index increases. When the index reaches the length of the array, it reset returns to zero. Here is an example (I use 0 instead of None for a dummy value just because it's faster to type):

 [0,0,0,0,0] ^ # add 1 [1,0,0,0,0] ^ # add 2 [1,2,0,0,0] ^ # add 3 [1,2,3,0,0] ^ # add 4 [1,2,3,4,0] ^ # add 5 [1,2,3,4,5] ^ # add 6 [6,2,3,4,5] ^ # add 7 [6,7,3,4,5] ^ 

etc.

+5
source share

The class can be quite trivial:

 class ListOfFive: def __init__(self): self.data = [] def add(self,val): if len(self.data)==5: self.data=self.data[1:]+[val] else: self.data+=[val] l = ListOfFive() for i in range(1,10): l.add(i) print l.data 

Exit:

 [1] [1, 2] [1, 2, 3] [1, 2, 3, 4] [1, 2, 3, 4, 5] [2, 3, 4, 5, 6] [3, 4, 5, 6, 7] [4, 5, 6, 7, 8] [5, 6, 7, 8, 9] 
+4
source share

Another neat buffer buffer implementation can be found in ActiveState Recipes - your ring buffer object starts as an instance of RingBuffer when populated first, and then your instance changes its class to RingBufferFull, an optimized full implementation. It always makes me smile.

 class RingBuffer: def __init__(self,size_max): self.max = size_max self.data = [] def append(self,x): """append an element at the end of the buffer""" self.data.append(x) if len(self.data) == self.max: self.cur=0 self.__class__ = RingBufferFull def get(self): """ return a list of elements from the oldest to the newest""" return self.data class RingBufferFull: def __init__(self,n): raise "you should use RingBuffer" def append(self,x): self.data[self.cur]=x self.cur=(self.cur+1) % self.max def get(self): return self.data[self.cur:]+self.data[:self.cur] 
+2
source share

From your description, I would add the following type of instruction right after the code that extends your list:

 mylist = mylist[-5:] 

It will ever be a maximum of 5 lengths

Here is a quick example:

 >>> mylist = [] >>> i = 1 >>> while i<6: print ("\n Pre addition: %r" % mylist) mylist += range(i) print (" Addition: %r" % mylist) mylist = mylist[-5:] print (" Chopped: %r" % mylist) i += 1 Pre addition: [] Addition: [0] Chopped: [0] Pre addition: [0] Addition: [0, 0, 1] Chopped: [0, 0, 1] Pre addition: [0, 0, 1] Addition: [0, 0, 1, 0, 1, 2] Chopped: [0, 1, 0, 1, 2] Pre addition: [0, 1, 0, 1, 2] Addition: [0, 1, 0, 1, 2, 0, 1, 2, 3] Chopped: [2, 0, 1, 2, 3] Pre addition: [2, 0, 1, 2, 3] Addition: [2, 0, 1, 2, 3, 0, 1, 2, 3, 4] Chopped: [0, 1, 2, 3, 4] >>> 
0
source share

All Articles