Question presented to candidate:
"I often see loops like for i in range(len(items)). What do enumerate and zip do, how would you use them to clean that up, and is there anything surprising about how they behave?"
What a strong answer should cover:
enumerate(iterable, start=0)yields(index, item)pairs, so you never index back into the list;start=sets the first number.zip(a, b, ...)yields tuples that take one item from each input, and stops as soon as the shortest input runs out.- Both return lazy, single-use iterators (
iter(e) is e), not lists; they work on any iterable, including generators and infinite ones. zip(..., strict=True)(Python 3.10, PEP 618) raisesValueErroron a length mismatch;itertools.zip_longestpads instead.- Idioms:
dict(zip(keys, values)),zip(*rows)to transpose or unzip,enumerate(zip(a, b))for index plus pairs. - The lost-item gotcha: zip pulls from the left input first, so an iterator passed on the left loses one item when a later input runs out.
Code / implementation expected: Yes β rewrite an index loop with enumerate, walk two lists with zip, and show zip(*rows) or dict(zip(...)).