Claude Code for more-itertools: Extended Iterator Tools in Python — Claude Skills 360 Blog
Blog / AI / Claude Code for more-itertools: Extended Iterator Tools in Python
AI

Claude Code for more-itertools: Extended Iterator Tools in Python

Published: April 15, 2028
Read time: 5 min read
By: Claude Skills 360

more-itertools extends Python’s itertools with 200+ recipes and new utilities. pip install more-itertools. Chunked: from more_itertools import chunked; list(chunked([1,2,3,4,5], 2))[[1,2],[3,4],[5]]. Batched: batched(range(7), 3) → groups of 3 (Python 3.12+ also in itertools). Sliced: sliced([1..10], 3). Windowed: windowed(seq, 3) — sliding window. Pairwise: pairwise([1,2,3])(1,2),(2,3). First: first([3,4,5]) → 3. Last: last([1,2,3]) → 3. One: one([42]) → 42. Only: only([42]) → 42. Flatten: more_itertools.flatten([[1,2],[3]]). Collapse: collapse([[1,[2,3]],4]). Roundrobin: roundrobin([1,2],[3],[4,5,6]). Interleave: more_itertools.interleave([1,2],[3,4]). Peekable: p = peekable([1,2,3]); p.peek(). Seekable: s = seekable(range(5)); s.seek(0). Bucket: b = bucket(range(10), key=even); list(b[True]). Groupby_transform: groupby_transform(seq, key, value). Unique_everseen: unique_everseen([1,1,2,2,3]). Unique_justseen: unique_justseen([1,1,2,3,3]) — run-length dedup. Partition: odd, even = partition(lambda x: x%2, range(10)). Divide: list(divide(3, range(9))). Zip_equal: zip_equal([1,2],[3,4]) — raises on length mismatch. Mark_ends: mark_ends([1,2,3])(True,False,1),(False,False,2),(False,True,3). Spy: head, it = spy(range(100), 3). Prepend: prepend(0, range(1,5)). take, tail, strip_func, before_and_after. Claude Code generates more-itertools sequence processors, sliding window analytics, and iterator pipelines.

CLAUDE.md for more-itertools

## more-itertools Stack
- Version: more-itertools >= 10.0 | pip install more-itertools
- Chunks: chunked(seq, n) | batched(seq, n) | divide(n, seq) | sliced(seq, n)
- Windows: windowed(seq, n) | pairwise(seq) | triplewise(seq)
- Dedup: unique_everseen(seq) | unique_justseen(seq) — global vs run-length
- Extract: first/last/one/only | nth(seq, n) | nth_or_last
- Advanced: peekable(seq) | seekable(seq) | bucket(seq, key) | spy(seq, n)
- Merge: roundrobin | interleave_longest | zip_equal | mark_ends | prepend

more-itertools Sequence Pipeline

# app/iter_utils.py — more-itertools chunking, windows, dedup, extract, and merge
from __future__ import annotations

from typing import Any, Callable, Iterable, Iterator, TypeVar

import more_itertools as mit

T = TypeVar("T")


# ─────────────────────────────────────────────────────────────────────────────
# 1. Chunking and splitting
# ─────────────────────────────────────────────────────────────────────────────

def chunks(seq: Iterable[T], size: int) -> list[list[T]]:
    """Split seq into lists of at most size elements. Last chunk may be shorter."""
    return [list(c) for c in mit.chunked(seq, size)]


def equal_chunks(seq: Iterable[T], n: int) -> list[list[T]]:
    """
    Split seq into exactly n chunks of (nearly) equal size.
    Uses more_itertools.divide — all chunks have the same length or differ by 1.
    """
    return [list(c) for c in mit.divide(n, seq)]


def sliced_list(seq: list[T], size: int) -> list[list[T]]:
    """Slice a concrete list into slices of size. Avoids copying."""
    return [list(seq[i:i+size]) for i in range(0, len(seq), size)]


def batch_iter(seq: Iterable[T], size: int) -> Iterator[tuple[T, ...]]:
    """Yield tuples of up to size items."""
    return mit.batched(seq, size)


# ─────────────────────────────────────────────────────────────────────────────
# 2. Sliding windows
# ─────────────────────────────────────────────────────────────────────────────

def windows(seq: Iterable[T], n: int, fillvalue: T | None = None) -> list[tuple]:
    """
    Sliding windows of width n.
    fillvalue pads shorter windows at the tail (default None pads too).
    """
    return list(mit.windowed(seq, n, fillvalue=fillvalue))


def pairs(seq: Iterable[T]) -> list[tuple[T, T]]:
    """Adjacent pairs: (seq[0],seq[1]), (seq[1],seq[2]), ..."""
    return list(mit.pairwise(seq))


def triples(seq: Iterable[T]) -> list[tuple[T, T, T]]:
    """Adjacent triples."""
    return list(mit.triplewise(seq))


def moving_average(seq: Iterable[float], n: int) -> list[float]:
    """Compute simple moving average with window size n."""
    ws = windows(seq, n)
    return [sum(w) / n for w in ws if None not in w]


def compute_diffs(seq: Iterable[float]) -> list[float]:
    """Return first differences: seq[i+1] - seq[i]."""
    return [b - a for a, b in pairs(seq)]


def detect_changes(seq: Iterable[T]) -> list[tuple[int, T, T]]:
    """Return list of (index, from_value, to_value) wherever seq changes."""
    return [
        (i + 1, a, b)
        for i, (a, b) in enumerate(pairs(seq))
        if a != b
    ]


# ─────────────────────────────────────────────────────────────────────────────
# 3. Deduplication
# ─────────────────────────────────────────────────────────────────────────────

def unique(seq: Iterable[T], key: Callable | None = None) -> list[T]:
    """Remove all duplicate values, preserving first-seen order."""
    return list(mit.unique_everseen(seq, key=key))


def unique_consecutive(seq: Iterable[T], key: Callable | None = None) -> list[T]:
    """
    Remove consecutive duplicate values (run-length dedup).
    [1,1,2,3,3,3,2] → [1,2,3,2]
    """
    return list(mit.unique_justseen(seq, key=key))


def run_lengths(seq: Iterable[T]) -> list[tuple[T, int]]:
    """
    Compute (value, count) run-length encoding.
    [1,1,2,3,3] → [(1,2),(2,1),(3,2)]
    """
    return [(val, sum(1 for _ in grp))
            for val, grp in mit.run_length.encode(seq)]


# ─────────────────────────────────────────────────────────────────────────────
# 4. Extraction helpers
# ─────────────────────────────────────────────────────────────────────────────

def first(seq: Iterable[T], default: T | None = None) -> T | None:
    """Return first item or default."""
    return mit.first(seq, default=default)


def last(seq: Iterable[T], default: T | None = None) -> T | None:
    """Return last item or default."""
    return mit.last(seq, default=default)


def nth(seq: Iterable[T], n: int, default: T | None = None) -> T | None:
    """Return the nth item (0-indexed) or default."""
    return mit.nth(seq, n, default=default)


def one(seq: Iterable[T], too_short=None, too_long=None) -> T:
    """
    Return the single item in seq.
    Raises ValueError (or custom exception) if seq has != 1 item.
    """
    return mit.one(seq, too_short=too_short, too_long=too_long)


def only(seq: Iterable[T], default: T | None = None) -> T | None:
    """Return the single item if seq has exactly one, else default."""
    return mit.only(seq, default=default)


def head_tail(seq: Iterable[T], n: int = 1) -> tuple[list[T], Iterator[T]]:
    """
    Peek at the first n items without consuming the iterator.
    Returns (head_list, full_iterator_from_start).
    """
    return mit.spy(seq, n)


# ─────────────────────────────────────────────────────────────────────────────
# 5. Partitioning and classification
# ─────────────────────────────────────────────────────────────────────────────

def split(seq: Iterable[T], predicate: Callable[[T], bool]) -> tuple[list[T], list[T]]:
    """
    Partition seq into (matches, non-matches) based on predicate.
    Returns (true_items, false_items).
    """
    no_match, match = mit.partition(predicate, seq)
    return list(match), list(no_match)


def classify(seq: Iterable[T], key: Callable[[T], Any]) -> dict[Any, list[T]]:
    """
    Classify items into groups by key function.
    Unlike itertools.groupby, does not require sorted input.
    """
    b = mit.bucket(seq, key=key)
    all_keys = set(key(x) for x in seq)  # noqa — bucket exhausts seq
    # bucket is lazy; re-iterate for keys
    results: dict[Any, list[T]] = {}
    for k in all_keys:
        results[k] = list(b[k])
    return results


def before_and_after_split(
    seq: Iterable[T], predicate: Callable[[T], bool]
) -> tuple[list[T], list[T]]:
    """
    Split seq into before-first-True and from-first-True.
    """
    before, after = mit.before_and_after(predicate, seq)
    return list(before), list(after)


def mark(seq: Iterable[T]) -> list[tuple[bool, bool, T]]:
    """
    Annotate each item with (is_first, is_last).
    Useful for rendering templates: add separator except after last item.
    """
    return [(first, last, val) for first, last, val in mit.mark_ends(seq)]


# ─────────────────────────────────────────────────────────────────────────────
# 6. Merging iterables
# ─────────────────────────────────────────────────────────────────────────────

def roundrobin(*seqs: Iterable[T]) -> list[T]:
    """Interleave seqs round-robin until all are exhausted."""
    return list(mit.roundrobin(*seqs))


def interleave(*seqs: Iterable[T], fillvalue: T | None = None) -> list[T | None]:
    """Interleave seqs, padding shorter ones with fillvalue."""
    return list(mit.interleave_longest(*seqs, fillvalue=fillvalue))


def safe_zip(*seqs: Iterable[T]) -> list[tuple[T, ...]]:
    """
    Zip sequences, raising ValueError if lengths differ.
    Use instead of zip() when lengths should always match.
    """
    return list(mit.zip_equal(*seqs))


def prepend_item(item: T, seq: Iterable[T]) -> list[T]:
    """Return list with item prepended."""
    return list(mit.prepend(item, seq))


def flatten_once(seq: Iterable[Iterable[T]]) -> list[T]:
    """Flatten one level of nesting."""
    return list(mit.flatten(seq))


def flatten_deep(seq: Iterable) -> list:
    """Recursively flatten all levels of nesting."""
    return list(mit.collapse(seq))


# ─────────────────────────────────────────────────────────────────────────────
# Demo
# ─────────────────────────────────────────────────────────────────────────────

if __name__ == "__main__":
    print("=== chunks ===")
    print(chunks(range(10), 3))

    print("\n=== equal_chunks ===")
    print(equal_chunks(range(10), 3))

    print("\n=== sliding windows + moving avg ===")
    prices = [10, 12, 11, 14, 13, 15, 16]
    avg3 = moving_average(prices, 3)
    print("prices:", prices)
    print("3-avg: ", [round(v, 2) for v in avg3])

    print("\n=== pairs + diffs ===")
    vals = [100, 103, 98, 105, 110]
    print("diffs:", compute_diffs(vals))

    print("\n=== detect_changes ===")
    statuses = ["ok","ok","fail","fail","ok","ok","fail"]
    print("changes:", detect_changes(statuses))

    print("\n=== unique + unique_consecutive ===")
    data = [1, 1, 2, 3, 2, 1, 2, 2]
    print("unique:       ", unique(data))
    print("unique_consec:", unique_consecutive(data))

    print("\n=== run_lengths ===")
    print(run_lengths("aaabbbccddddee"))

    print("\n=== extraction ===")
    items = [10, 20, 30, 40]
    print("first:", first(items), "| last:", last(items))
    print("nth(2):", nth(items, 2))
    print("one([42]):", one([42]))

    print("\n=== split + mark ===")
    nums = list(range(10))
    evens, odds = split(nums, lambda x: x % 2 == 0)
    print("evens:", evens, " odds:", odds)
    for is_first, is_last, val in mark(["a", "b", "c"]):
        sep = "" if is_last else ", "
        print(f"  (first={is_first}, last={is_last}) {val!r}{sep}", end="")
    print()

    print("\n=== roundrobin + safe_zip ===")
    print("roundrobin:", roundrobin([1,4], [2,5], [3,6,7]))
    print("safe_zip:  ", safe_zip([1,2,3], [4,5,6]))

    print("\n=== flatten ===")
    nested = [[1,2],[3,[4,5]],[[6,[7]]]]
    print("flatten_once:", flatten_once([[1,2],[3,4],[5]]))
    print("flatten_deep:", flatten_deep(nested))

    print("\n=== head_tail spy ===")
    gen = (x*x for x in range(1, 6))
    head, full = head_tail(gen, 2)
    print("peek:", head, "| full:", list(full))

For the itertools stdlib alternative — itertools has ~20 functions covering the basics (chain, islice, groupby, product); more-itertools has 200+ recipes and fills gaps like chunked, windowed, pairwise, unique_everseen, roundrobin, mark_ends, and zip_equal that you’d otherwise need to write yourself. For the toolz alternative — toolz focuses on functional programming patterns (pipe, compose, curry, merge_with) and dict/groupby operations; more-itertools focuses on iterator manipulation (windows, chunking, run-lengths, head/tail inspection) — they’re complementary; use toolz for functional composition and more-itertools for sequence manipulation. The Claude Skills 360 bundle includes more-itertools skill sets covering chunks/batch/divide/sliced, windows/pairs/triples/moving_average, compute_diffs/detect_changes, unique/unique_consecutive/run_lengths, first/last/nth/one/only/head_tail extraction, split/classify/before_and_after_split/mark, roundrobin/interleave/safe_zip/prepend_item, flatten_once/flatten_deep, and full demo with analytics examples. Start with the free tier to try iterator pipeline code generation.

Keep Reading

AI

Claude Code for email.contentmanager: Python Email Content Accessors

Read and write EmailMessage body content with Python's email.contentmanager module and Claude Code — email contentmanager ContentManager for the class that maps content types to get and set handler functions allowing EmailMessage to support get_content and set_content with type-specific behaviour, email contentmanager raw_data_manager for the ContentManager instance that handles raw bytes and str payloads without any conversion, email contentmanager content_manager for the standard ContentManager instance used by email.policy.default that intelligently handles text plain text html multipart and binary content types, email contentmanager get_content_text for the handler that returns the decoded text payload of a text-star message part as a str, email contentmanager get_content_binary for the handler that returns the raw decoded bytes payload of a non-text message part, email contentmanager get_data_manager for the get-handler lookup used by EmailMessage get_content to find the right reader function for the content type, email contentmanager set_content text for the handler that creates and sets a text part correctly choosing charset and transfer encoding, email contentmanager set_content bytes for the handler that creates and sets a binary part with base64 encoding and optional filename Content-Disposition, email contentmanager EmailMessage get_content for the method that reads the message body using the registered content manager handlers, email contentmanager EmailMessage set_content for the method that sets the message body and MIME headers in one call, email contentmanager EmailMessage make_alternative make_mixed make_related for the methods that convert a simple message into a multipart container, email contentmanager EmailMessage add_attachment for the method that attaches a file or bytes to a multipart message, and email contentmanager integration with email.message and email.policy and email.mime and io for building high-level email readers attachment extractors text body accessors HTML readers and policy-aware MIME construction pipelines.

5 min read Feb 12, 2029
AI

Claude Code for email.charset: Python Email Charset Encoding

Control header and body encoding for international email with Python's email.charset module and Claude Code — email charset Charset for the class that wraps a character set name with the encoding rules for header encoding and body encoding describing how to encode text for that charset in email messages, email charset Charset header_encoding for the attribute specifying whether headers using this charset should use QP quoted-printable encoding BASE64 encoding or no encoding, email charset Charset body_encoding for the attribute specifying the Content-Transfer-Encoding to use for message bodies in this charset such as QP or BASE64, email charset Charset output_codec for the attribute giving the Python codec name used to encode the string to bytes for the wire format, email charset Charset input_codec for the attribute giving the Python codec name used to decode incoming bytes to str, email charset Charset get_output_charset for returning the output charset name, email charset Charset header_encode for encoding a header string using the charset's header_encoding method, email charset Charset body_encode for encoding body content using the charset's body_encoding, email charset Charset convert for converting a string from the input_codec to the output_codec, email charset add_charset for registering a new charset with custom encoding rules in the global charset registry, email charset add_alias for adding an alias name that maps to an existing registered charset, email charset add_codec for registering a codec name mapping for use by the charset machinery, and email charset integration with email.message and email.mime and email.policy and email.encoders for building international email senders non-ASCII header encoders Content-Transfer-Encoding selectors charset-aware message constructors and MIME encoding pipelines.

5 min read Feb 11, 2029
AI

Claude Code for email.utils: Python Email Address and Header Utilities

Parse and format RFC 2822 email addresses and dates with Python's email.utils module and Claude Code — email utils parseaddr for splitting a display-name plus angle-bracket address string into a realname and email address tuple, email utils formataddr for combining a realname and address string into a properly quoted RFC 2822 address with angle brackets, email utils getaddresses for parsing a list of raw address header strings each potentially containing multiple comma-separated addresses into a list of realname address tuples, email utils parsedate for parsing an RFC 2822 date string into a nine-tuple compatible with time.mktime, email utils parsedate_tz for parsing an RFC 2822 date string into a ten-tuple that includes the UTC offset timezone in seconds, email utils parsedate_to_datetime for parsing an RFC 2822 date string into an aware datetime object with timezone, email utils formatdate for formatting a POSIX timestamp or the current time as an RFC 2822 date string with optional usegmt and localtime flags, email utils format_datetime for formatting a datetime object as an RFC 2822 date string, email utils make_msgid for generating a globally unique Message-ID string with optional idstring and domain components, email utils decode_rfc2231 for decoding an RFC 2231 encoded parameter value into a tuple of charset language and value, email utils encode_rfc2231 for encoding a string as an RFC 2231 encoded parameter value, email utils collapse_rfc2231_value for collapsing a decoded RFC 2231 tuple to a Unicode string, and email utils integration with email.message and email.headerregistry and datetime and time for building address parsers date formatters message-id generators header extractors and RFC-compliant email construction utilities.

5 min read Feb 10, 2029

Put these ideas into practice

Claude Skills 360 gives you production-ready skills for everything in this article — and 2,350+ more. Start free or go all-in.

Back to Blog

Get 360 skills free