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