Placement Prep

Python itertools for Placements: 7 Functions That Matter

Master Python's itertools module with verified examples covering chain, permutations, combinations, product, groupby, count, and cycle for placement coding rounds.

By FACE Prep Team 6 min read
python itertools placement-prep coding-interview aptitude data-structures

Python’s itertools module packs memory-efficient iterator functions into the standard library, requiring no pip install and no extra dependencies. The seven functions most common in placement coding rounds are chain, combinations, permutations, product, groupby, count, and cycle. All seven use lazy evaluation: they yield values on demand rather than computing the full result upfront.

Lazy evaluation matters for two practical reasons. First, it keeps memory usage flat even when the logical output is enormous: product([0, 1], repeat=20) describes over one million binary strings but never stores all of them at once. Second, it lets you short-circuit: wrap any infinite itertools iterator with islice or a break condition and you pay only for what you consume.

What itertools Does

The Python itertools documentation describes the module as building blocks inspired by APL, Haskell, and SML. The practical description: a toolkit for writing loops that are shorter, faster, and kinder to memory than the equivalent hand-rolled versions.

Every itertools function satisfies the Python iterator protocol, which requires __iter__ and __next__ methods. Because the interface is uniform, itertools functions compose freely with generators, custom classes, and file objects. chain(permutations([1, 2, 3], 2), combinations([1, 2, 3], 2)) works without any intermediate list conversion.

The module also includes islice for slicing any iterator, accumulate for running totals, and repeat for fixed-count repetition. This article focuses on the seven functions that appear most in placement coding tests.

Import only what you use:

from itertools import chain, combinations, permutations, product, groupby, count, cycle

Importing named functions (rather than from itertools import *) keeps the namespace clean and signals to the next reader exactly which tools the code uses.

Infinite Iterators: count and cycle

count(start, step) produces an infinite arithmetic sequence. Use it wherever you need a running index but don’t know the length ahead of time.

from itertools import count

for n in count(5, 2):
    if n > 15:
        break
    print(n)
# Output: 5  7  9  11  13  15

Verified by hand:

  • n = 5: 5 is not greater than 15, print 5
  • n = 7: print 7
  • n = 9: print 9
  • n = 11: print 11
  • n = 13: print 13
  • n = 15: 15 is not greater than 15, print 15
  • n = 17: 17 is greater than 15, break

Output: 5, 7, 9, 11, 13, 15. Six values, all correct.

A second pattern that appears in grid-indexing problems uses islice to cap the output cleanly:

from itertools import count, islice

indices = list(islice(count(0, 5), 6))
# [0, 5, 10, 15, 20, 25]

islice(iterable, n) takes only the first n elements from any iterator. It is the standard way to cap an infinite sequence without a manual break. Think of it as Python’s slicing syntax applied to iterators that don’t support [start:stop] indexing.

cycle(iterable) loops through a finite sequence indefinitely. A common coding question pattern: given a list of servers, distribute n requests in round-robin order.

from itertools import cycle

servers = cycle(['S1', 'S2', 'S3'])
for _ in range(5):
    print(next(servers))
# Output: S1  S2  S3  S1  S2

Verified: five calls to next on a three-element cycle produce S1, S2, S3, S1, S2. The cycle restarts after the last element.

A variant that shows up in task-scheduling problems:

from itertools import cycle

workers = cycle(['Alice', 'Bob', 'Carol'])
tasks = ['T1', 'T2', 'T3', 'T4', 'T5']
assignments = {task: next(workers) for task in tasks}
# {'T1': 'Alice', 'T2': 'Bob', 'T3': 'Carol', 'T4': 'Alice', 'T5': 'Bob'}

Verified: five tasks, three workers cycling give T1=Alice, T2=Bob, T3=Carol, T4=Alice, T5=Bob.

Combinatorics in One Line: permutations, combinations, and product

These three functions cover the combinatorics problems that appear in every placement aptitude and coding round.

FunctionOrder mattersRepetitionFormula
permutations(iterable, r)YesNoP(n,r) = n times (n-1) times … times (n-r+1)
combinations(iterable, r)NoNoC(n,r) = P(n,r) / r factorial
product(*iterables, repeat=r)YesYesn^r for a single n-element iterable

For the three-letter set ['A', 'B', 'C']:

from itertools import permutations, combinations, product

letters = ['A', 'B', 'C']

print(list(permutations(letters, 2)))
# [('A','B'), ('A','C'), ('B','A'), ('B','C'), ('C','A'), ('C','B')]

print(list(combinations(letters, 2)))
# [('A','B'), ('A','C'), ('B','C')]

print(list(product([0, 1], repeat=2)))
# [(0,0), (0,1), (1,0), (1,1)]

Verified counts:

  • Permutations of 2 from 3: P(3,2) = 3 × 2 = 6 tuples. The list shows 6 tuples.
  • Combinations of 2 from 3: C(3,2) = P(3,2) / 2 factorial = 6 / 2 = 3 tuples. The list shows 3 tuples.
  • product of [0,1] with repeat=2: 2 × 2 = 4 tuples. The list shows 4 tuples.

A classic placement question: how many distinct 3-letter arrangements can be formed from the letters P, Y, T, H, O, N?

  • With permutations('PYTHON', 3), each of the 6 unique characters can occupy each position once.
  • P(6,3) = 6 × 5 × 4 = 120.
  • len(list(permutations('PYTHON', 3))) returns 120. Verified.

A product pattern for a practical problem: a restaurant has 3 starters and 2 mains. How many unique two-course meals?

from itertools import product

starters = ['S1', 'S2', 'S3']
mains = ['M1', 'M2']
meals = list(product(starters, mains))
print(len(meals))  # 6

Verified: 3 × 2 = 6. product gives the Cartesian product: every combination of one element from each input list.

Chaining and Grouping: chain and groupby

chain(*iterables) connects multiple iterables into one continuous sequence without allocating an intermediate list.

from itertools import chain

merged = list(chain([1, 2], ['A', 'B'], [True]))
# [1, 2, 'A', 'B', True]

Verified: three input lists of lengths 2, 2, and 1 merge into a single output of 5 elements.

A second pattern: aggregating scores from separate quiz rounds without flattening to a new list.

from itertools import chain

q1 = [8, 7, 6]
q2 = [9, 5]
q3 = [8, 8, 7]
total = sum(chain(q1, q2, q3))
# 58

Verified: 8 + 7 + 6 + 9 + 5 + 8 + 8 + 7 = 58. chain processes the lists one by one without ever allocating a merged list.

groupby(iterable, key) groups consecutive identical keys. It is the pure-Python equivalent of SQL’s GROUP BY clause, with one important difference: SQL automatically handles unsorted input, but Python’s groupby does not. Always sort the input data first, then group.

from itertools import groupby

data = [('Alice', 'pass'), ('Carol', 'pass'), ('Bob', 'fail')]
data_sorted = sorted(data, key=lambda x: x[1])

for status, group in groupby(data_sorted, key=lambda x: x[1]):
    names = [row[0] for row in group]
    print(f"{status}: {names}")
# fail: ['Bob']
# pass: ['Alice', 'Carol']

Verified: after sorting by status, the data becomes [('Bob', 'fail'), ('Alice', 'pass'), ('Carol', 'pass')]. groupby sees ‘fail’ once (1 entry) then ‘pass’ twice (2 entries). Output: fail with Bob, pass with Alice and Carol.

What happens without sorting:

# Unsorted input -- groupby treats non-consecutive keys as separate groups
data_unsorted = [('Alice', 'pass'), ('Bob', 'fail'), ('Carol', 'pass')]
for status, group in groupby(data_unsorted, key=lambda x: x[1]):
    print(status, list(group))
# pass [('Alice', 'pass')]
# fail [('Bob', 'fail')]
# pass [('Carol', 'pass')]   <- separate group for the second 'pass'

The data has two ‘pass’ entries, but they produce two separate groups because they are not consecutive. Always sort before calling groupby.

itertools in Placement Coding Rounds

Placement aptitude and coding rounds consistently include combinatorics problems that map directly to these functions. A pattern inventory:

Problem patternitertools solution
All k-subsets of a setcombinations(items, k)
All ordered arrangements of r itemspermutations(items, r)
All n-bit binary stringsproduct([0, 1], repeat=n)
Round-robin task assignmentcycle(workers)
Merge k sorted arrays sequentiallychain(*arrays)
Group records by a fieldsorted(data, key=...) then groupby

The efficiency argument is concrete. Generating all 2-element combinations from a 10-element list with nested for-loops requires roughly 10 lines and is prone to off-by-one errors. combinations(items, 2) is 1 line and correct by design.

For the campus placement evaluation tests that many Indian colleges run before final placements, the coding section consistently includes at least one combinatorics problem. Candidates who reach for itertools solve it in the time others spend debugging loop boundaries.

At companies known for strong quantitative hiring, such as those covered in the D.E. Shaw placement guide, combinatorics problems test mathematical reasoning speed alongside coding ability. A one-line itertools solution reads as clearly as the problem statement itself.

For broader Python and algorithm resources useful in placement preparation, the best books for placement preparation covers titles that include coding interview content alongside aptitude prep.

The combinatorics patterns in this article (subsets, arrangements, Cartesian products) appear in a different form in LLM engineering: iterating over prompt variants, sampling from a parameter search space, and composing chains of API calls. TinkerLLM at ₹299 provides a Python notebook environment where these exact itertools patterns run against live LLM APIs. It’s a different problem from placement prep, but the iterator thinking transfers directly.

Primary sources

Frequently asked questions

Is itertools faster than a regular for loop in Python?

itertools functions are implemented in C, making them faster than equivalent pure-Python loops for large datasets. The bigger gain is memory: lazy evaluation means the full sequence is never loaded into RAM at once.

Does itertools work with generators and custom iterators?

Yes. Any object that implements __iter__ and __next__ works with all itertools functions. You can pass a generator directly into itertools.chain without converting it to a list first.

When should I use combinations instead of permutations?

Use combinations when order does not matter, such as choosing 3 students from a class of 30. Use permutations when order matters, such as ranking 3 students from a class of 30. The difference in output size grows fast: P(10,3) = 720 but C(10,3) = 120.

Why does groupby give unexpected results on unsorted input?

groupby groups only consecutive identical keys. If your list is [A, B, A], groupby sees three separate groups, not two. Sort by the grouping key first using sorted() to get the expected behaviour.

Which itertools functions appear most in placement coding tests?

permutations, combinations, and product appear most in aptitude-style combinatorics problems. chain is common in list-merge tasks. groupby comes up in data-processing questions at analytics companies.

Build AI projects

A self-paced playground for building with LLMs.

TinkerLLM is FACE Prep's sister property. A guided environment for shipping real LLM applications, the kind of project that earns a paragraph on your resume, not a line.

Try TinkerLLM (₹299 launch)
Free AI Roadmap PDF