[{"data":1,"prerenderedAt":71},["ShallowReactive",2],{"qa-\u002Fpython\u002Ffunctional\u002Fitertools":3},{"page":4,"siblings":62,"blog":53},{"id":5,"title":6,"body":7,"description":11,"difficulty":14,"extension":15,"framework":16,"frameworkSlug":17,"meta":18,"navigation":19,"order":20,"path":21,"questions":22,"related":53,"seo":54,"seoDescription":55,"stem":56,"subtopic":57,"topic":58,"topicSlug":59,"updated":60,"__hash__":61},"qa\u002Fpython\u002Ffunctional\u002Fitertools.md","Itertools",{"type":8,"value":9,"toc":10},"minimark",[],{"title":11,"searchDepth":12,"depth":12,"links":13},"",2,[],"medium","md","Python","python",{},true,3,"\u002Fpython\u002Ffunctional\u002Fitertools",[23,27,32,36,40,45,49],{"id":24,"difficulty":14,"q":25,"a":26},"infinite-iterators","What do count, cycle, and repeat do?","These are the three **infinite iterators**. **`count(start, step)`** yields an\nendless arithmetic sequence. **`cycle(iterable)`** repeats an iterable's items\nforever. **`repeat(value, times)`** yields the same value endlessly, or `times`\ntimes if given.\n\n```python\nfrom itertools import count, cycle, repeat, islice\n\nlist(islice(count(10, 2), 3))      # [10, 12, 14]\nlist(islice(cycle(\"AB\"), 5))       # ['A', 'B', 'A', 'B', 'A']\nlist(repeat(7, 3))                 # [7, 7, 7]\n```\n\nBecause `count` and `cycle` never stop, you must bound them — with `islice`, `zip`,\nor a `break` — or your loop runs forever. They're ideal for generating ids,\nround-robin assignment, or padding.\n",{"id":28,"difficulty":29,"q":30,"a":31},"chain","easy","What does itertools.chain do?","`chain(*iterables)` lazily **concatenates** multiple iterables into one stream,\nwithout building an intermediate combined list. `chain.from_iterable(iter_of_iters)`\ndoes the same when the iterables come from a single iterable (e.g. a list of lists).\n\n```python\nfrom itertools import chain\n\nlist(chain([1, 2], [3, 4], [5]))        # [1, 2, 3, 4, 5]\n\nrows = [[1, 2], [3, 4], [5, 6]]\nlist(chain.from_iterable(rows))         # [1, 2, 3, 4, 5, 6] — flatten one level\n```\n\nIt's the memory-friendly way to iterate over several sequences as if they were one,\nand the idiomatic one-level flatten.\n",{"id":33,"difficulty":14,"q":34,"a":35},"islice","What is islice and how is it different from regular slicing?","`islice(iterable, stop)` or `islice(iterable, start, stop, step)` slices any\n**iterator lazily** — including infinite ones and generators that don't support\n`[ ]` indexing. Unlike list slicing, it **can't use negative indices** (it can't\nlook backward in a stream) and it **consumes** the underlying iterator.\n\n```python\nfrom itertools import islice, count\n\nlist(islice(count(), 2, 7))      # [2, 3, 4, 5, 6] — works on an infinite source\ngen = (x * x for x in range(10))\nlist(islice(gen, 3))             # [0, 1, 4] — slice a generator\n```\n\nUse `islice` to take a window from a stream without materializing it. For a concrete\nlist where you want negative indices, ordinary `seq[a:b]` is fine.\n",{"id":37,"difficulty":14,"q":38,"a":39},"combinatorics","What do combinations, permutations, and product produce?","These generate **combinatorial** results lazily. **`permutations(it, r)`** —\nordered arrangements (order matters). **`combinations(it, r)`** — unordered\nselections (order doesn't, no repeats). **`product(*its)`** — the Cartesian product\n(nested loops), with `repeat=n` for self-products.\n\n```python\nfrom itertools import permutations, combinations, product\n\nlist(permutations([1, 2, 3], 2))   # (1,2)(1,3)(2,1)(2,3)(3,1)(3,2)\nlist(combinations([1, 2, 3], 2))   # (1,2)(1,3)(2,3)\nlist(product([0, 1], repeat=2))    # (0,0)(0,1)(1,0)(1,1)\n```\n\nCounts grow fast (factorial \u002F exponential), so keep `r` and inputs small or consume\nlazily. `product(a, b)` replaces a nested `for` over two sequences.\n",{"id":41,"difficulty":42,"q":43,"a":44},"groupby","hard","Why does itertools.groupby require sorted input?","`groupby` groups **only consecutive** items that share a key — it does **not** sort\nfirst. So the same key appearing in non-adjacent positions creates **multiple\ngroups**. To get one group per key, **sort by the same key function first**.\n\n```python\nfrom itertools import groupby\n\ndata = [\"apple\", \"avocado\", \"banana\", \"apricot\"]\n# WRONG — not sorted: 'a' group splits because 'banana' is between\nfor k, g in groupby(data, key=lambda s: s[0]):\n    print(k, list(g))      # a [...] , b [...] , a [apricot]\n\ndata.sort(key=lambda s: s[0])      # sort by the SAME key\nfor k, g in groupby(data, key=lambda s: s[0]):\n    print(k, list(g))      # a [...], b [...]  — correct\n```\n\nAlso note each group is a **lazy sub-iterator** that's invalidated when you advance\nto the next group — materialize it with `list()` if you need it later. Always sort\nby the grouping key before `groupby`.\n",{"id":46,"difficulty":14,"q":47,"a":48},"accumulate","What does itertools.accumulate do?","`accumulate(iterable, func=operator.add)` yields **running totals** — each output is\nthe function applied cumulatively, so by default you get a running sum. Pass a\ndifferent binary `func` for running max, product, etc.\n\n```python\nfrom itertools import accumulate\nimport operator\n\nlist(accumulate([1, 2, 3, 4]))                 # [1, 3, 6, 10] — running sum\nlist(accumulate([1, 2, 3, 4], operator.mul))   # [1, 2, 6, 24] — running product\nlist(accumulate([3, 1, 4, 1, 5], max))         # [3, 3, 4, 4, 5] — running max\n```\n\nUnlike `functools.reduce`, which returns only the **final** value, `accumulate`\nyields **every intermediate** result lazily. Use it for prefix sums and similar\nscans.\n",{"id":50,"difficulty":14,"q":51,"a":52},"laziness-memory","What is the main benefit of itertools being lazy?","Every `itertools` function returns a **lazy iterator** that computes items **on\ndemand**, so it never holds the whole sequence in memory. This lets you process\n**huge or infinite** streams in **constant memory**, and chain operations into a\npipeline that only does the work actually consumed.\n\n```python\nfrom itertools import count, islice\n\n# find the first 5 squares over 1000 — from an infinite source\nsquares = (n * n for n in count(1))\nbig = (s for s in squares if s > 1000)\nprint(list(islice(big, 5)))    # computed lazily, nothing materialized\n\nsum(islice(count(1), 1_000_000))   # no million-element list built\n```\n\nThe trade-off is that iterators are **single-pass** and not indexable. Reach for\n`itertools` when streaming or composing transformations over large data;\nmaterialize to a list only when you need random access or multiple passes.\n",null,{"description":11},"Python interview questions on itertools — count\u002Fcycle\u002Frepeat, chain, islice, combinations\u002Fpermutations\u002Fproduct, groupby's sorted-input rule, accumulate, and the memory benefit of lazy iterators.","python\u002Ffunctional\u002Fitertools","itertools","Functional Programming","functional","2026-06-18","1Gxse2j1ry-O6nBlZJIbeCn668VKgt8dM8TEa8_-mMU",[63,67,70],{"subtopic":64,"path":65,"order":66},"functools","\u002Fpython\u002Ffunctional\u002Ffunctools",1,{"subtopic":68,"path":69,"order":12},"map, filter & reduce","\u002Fpython\u002Ffunctional\u002Fmap-filter-reduce",{"subtopic":57,"path":21,"order":20},1781808681178]