pythonfifo

FIFO class in python library?


Below is a simple implementation of a FIFO in Python. My question is whether anything equivalent already exists in a maintained package, especially anything in the standard library, as it seems like a reasonably common thing to want to do.

Functionality: you must be able to append to and iterate over it like a list, but when iteration yields an element, the internal reference to that element must be destroyed.

Here is example of what I want to do with it:

f = Fifo()

# append to it

for i in range(5):
    f.append(i)
print("length:", len(f))

# iterate over it, including appending while iterating

for i in f:
    print("item:", i)
    if i == 3:
        f.append("something")
print("all for now")

# iterate again (maybe we didn't previously iterate fully,
# or, as in this example, appended some more items afterwards)

f.append("another thing")
f.append("and another thing")
print("length:", len(f))
for i in f:
    print("item:", i)

to give:

length: 5
item: 0
item: 1
item: 2
item: 3
item: 4
item: something
all for now
length: 2
item: another thing
item: and another thing

And here is my implementation. (This uses a dictionary. A marginally simpler but less efficient alternative uses a list internally.)

class Fifo:

    def __init__(self):
        self._d = {}
        self._cur = 0  # next key to pop

    def __len__(self):
        return len(self._d)

    def append(self, v):
        self._d[self._cur + len(self._d)] = v

    def __next__(self):
        if self._d:
            v = self._d.pop(self._cur)
            self._cur += 1
            return v
        else:
            raise StopIteration

    def __iter__(self):
        return self

Solution

  • Are you looking for this?

    from queue import SimpleQueue
    
    
    class Fifo(SimpleQueue):
        def __iter__(self):
            return self
    
        def __len__(self):
            return self.qsize()
    
        def __next__(self):
            if not self.empty():
                return self.get()
            raise StopIteration
    
    fifo = Fifo()
    fifo.put(10)
    fifo.put(20)
    for item in fifo:
        print(item)
    
    print(f'fifo size after iteration {len(fifo)}')
    

    Output

    10
    20
    fifo size after iteration 0