简体   繁体   中英

What python deque-like containers retain valid iterators during mutation?

I see here that collections.deque is not a great choice if I want to retain valid iterators while mutating the data structure. Are there any data structures in python's stdlib that preserve valid iterators while supporting these two operations:

  • append - Append something to the end of the container in O(1) amortized
  • popleft - Pop something from the beginning of the container in O(1) amortized

Why would I want something like this?

Consider a class that generates a stream of data. There are multiple consumers that call __iter__ on this class to get an iterator to consume data in-order. For sake of simplicity, assume the __iter__ calls happen before any __next__ is called.

Suppose the stream is large enough that it could exceed reasonable memory limits. A reasonable thing to do is to use a deque, so that when an iterator is at the end of the deque, we block to wait for new data and append it. When all iterators have visited an element, we no longer need to keep it in memory, so we popleft .

The std::deque implementation in C++ uses circular list of buffers and allows us to have valid iterators upon these two operations. Is there something like this in python as well?

itertools.tee is designed for your use case exactly. Internally, it uses iterators pointing into a shared FIFO queue, but the data structure is internal to the tee implementation (which is written in C, at least in CPython).

Implementing a FIFO queue with iterators (your actual question) on top of tee would probably be possible, but it's tricky, in part because the iterator interface specifies that no more values can ever appear after StopIteration has been raised, while a typical FIFO can still be used after a failed pop.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM