CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-more-itertools

Additional building blocks, recipes, and routines for working with Python iterables beyond itertools.

Pending
Overview
Eval results
Files

lookahead.mddocs/

Lookahead and Lookback

Advanced iterator wrappers that provide peek and seek capabilities.

Capabilities

Peekable Iterator

Iterator wrapper that allows looking ahead without consuming items.

class peekable:
    """
    Iterator wrapper that allows peeking ahead.
    
    Provides methods to look at upcoming items without consuming them
    and to prepend items back to the iterator.
    """
    
    def __init__(self, iterable):
        """Initialize with an iterable."""
    
    def __iter__(self):
        """Return self as iterator."""
    
    def __next__(self):
        """Return next item from iterator."""
    
    def peek(self, default=None):
        """
        Return next item without consuming it.
        
        Args:
            default: Value to return if iterator is exhausted
            
        Returns:
            Next item or default if exhausted
        """
    
    def prepend(self, *values):
        """
        Prepend values to be yielded before continuing iteration.
        
        Args:
            *values: Values to prepend
        """
    
    def __bool__(self):
        """Return True if iterator has more items."""

Usage Examples:

from more_itertools import peekable

# Basic peeking
p = peekable([1, 2, 3, 4, 5])
print(p.peek())      # 1 (not consumed)
print(p.peek())      # 1 (still not consumed)
print(next(p))       # 1 (now consumed)
print(p.peek())      # 2

# Peek with default
p = peekable([])
print(p.peek('empty'))  # 'empty'

# Prepending values
p = peekable([3, 4, 5])
p.prepend(1, 2)
list(p)  # [1, 2, 3, 4, 5]

# Check if iterator has items
p = peekable([1, 2, 3])
while p:
    print(next(p))

Seekable Iterator

Iterator wrapper that allows seeking to specific positions.

class seekable:
    """
    Iterator wrapper that allows seeking to arbitrary positions.
    
    Caches items as they are consumed to enable seeking backwards.
    """
    
    def __init__(self, iterable):
        """Initialize with an iterable."""
    
    def __iter__(self):
        """Return self as iterator."""
    
    def __next__(self):
        """Return next item from iterator."""
    
    def seek(self, index):
        """
        Seek to absolute position in iterator.
        
        Args:
            index: Position to seek to (0-based)
        """
    
    def relative_seek(self, count):
        """
        Seek relative to current position.
        
        Args:
            count: Number of positions to move (can be negative)
        """
    
    @property
    def index(self):
        """Current position in the iterator."""

Usage Examples:

from more_itertools import seekable

# Basic seeking
s = seekable([10, 20, 30, 40, 50])
print(next(s))       # 10
print(next(s))       # 20
s.seek(0)           # Go back to start
print(next(s))       # 10
s.seek(4)           # Jump to position 4
print(next(s))       # 50

# Relative seeking
s = seekable([1, 2, 3, 4, 5])
next(s), next(s)    # Consume 1, 2 (now at position 2)
s.relative_seek(-1)  # Go back one position
print(next(s))       # 2

# Check current position
s = seekable([1, 2, 3])
next(s)
print(s.index)       # 1

Spy Function

Look ahead at the beginning of an iterable.

def spy(iterable, n=1):
    """
    Return first n items and an iterator for the full sequence.
    
    Args:
        iterable: Input iterable to spy on
        n: Number of items to peek at (default 1)
        
    Returns:
        Tuple of (first_n_items, full_iterator)
    """

Usage Examples:

from more_itertools import spy

# Spy on first item
first_items, iterator = spy([1, 2, 3, 4, 5])
print(first_items)   # [1]
print(list(iterator)) # [1, 2, 3, 4, 5]

# Spy on first 3 items
first_three, iterator = spy([1, 2, 3, 4, 5], 3)
print(first_three)   # [1, 2, 3]
print(list(iterator)) # [1, 2, 3, 4, 5]

# Use for conditional processing
data = range(1000)
preview, full_data = spy(data, 10)
if max(preview) > 5:
    # Process large numbers differently
    result = process_large_numbers(full_data)
else:
    result = process_small_numbers(full_data)

Install with Tessl CLI

npx tessl i tessl/pypi-more-itertools

docs

advanced-utilities.md

combinatorics.md

combining.md

comparison.md

grouping.md

index.md

indexing.md

iteration-utilities.md

lookahead.md

mathematical.md

random-operations.md

selecting.md

sequence-utilities.md

special-purpose.md

summarizing.md

uniqueness.md

utility-classes.md

windowing.md

tile.json