Suppose someone designs an indexable iterator class, i.e. an iterator that supports __getitem__ for (non-negative) integer indexes such as the following:
In [1] it = indexed_iter("abcdefghij")
In [2]: next(it)
Out[2]: 'a'
In [3]: next(it)
Out[3]: 'b'
In [4]: it[1]
Out[4]: ???
In [5]: it[2]
Out[5]: ???
In [6]: next(it)
Out[6]: ???
What is the most intuitive behavior for outputs 4-6? Some candidate options:
1a. it[0] is the item that would be returned by next, it[1] the item after than and so on. Additionally, the iterator is forwarded as a side-effect of indexing:
In [4]: it[1]
Out[4]: 'd'
In [5]: it[2]
Out[5]: 'g'
In [6]: next(it)
Out[6]: 'h'
1b. Same as (1a) but idempotent; the iterator is not forwarded by indexing:
In [4]: it[1]
Out[4]: 'd'
In [5]: it[2]
Out[5]: 'e'
In [6]: next(it)
Out[6]: 'c'
2a. it[0] is the first item (already or to be) returned by next, regardless of the current state of the iterator. Additionally, the iterator moves at the index position as a side-effect of indexing:
In [4]: it[1]
Out[4]: 'b'
In [5]: it[2]
Out[5]: 'c'
In [6]: next(it)
Out[6]: 'd'
2b. Same as (2a) but idempotent; the iterator's state does not change by indexing:
In [4]: it[1]
Out[4]: 'b'
In [5]: it[2]
Out[5]: 'c'
In [6]: next(it)
Out[6]: 'c'
- None of the above is intuitive, or at least more intuitive than the alternatives;
__getitem__should be supported at all for iterators.
This is a question about API design only; it's not about implementation, performance, memory implications or other concerns.