Typorithm · easy

Iteration, enumerate and complete boundaries

pythonscriptingdata-boundariesindependent-practice
Saved on this device
Full lesson · 4 learning steps Open any exercise for focused practice
1

Step 1 of 4 · intro card

Iteration, enumerate and complete boundaries

0%

Concept and contract

Visit each intended element once and distinguish a displayed position from a source index.

A for loop visits values from an iterable. When both the value and its position are needed, enumerate supplies them together. The worked function collects zero-based positions where a list member equals the requested target, without modifying the source list.

For QA, Dev, QA the matching positions are zero and two. The repeated target at the final position is intentional: it exposes a loop that stops too early. An empty input should produce an empty list rather than a fabricated first position or an index error.

Mechanism and worked example

enumerate starts at zero by default and advances with each yielded value.

enumerate starts at zero by default and advances with each yielded value. The loop's if selects matching values while append records their corresponding positions. The source order determines the returned order, so no separate sort is required for this simple positional traversal.

range has an exclusive stop boundary. A manual loop over range(len(values)) covers every valid list index, while subtracting one from that stop omits the final element. Prefer direct value iteration or enumerate when it expresses the contract without extra index arithmetic.

Complete worked example

python

def matching_positions(values, target):
    result = []
    for index, value in enumerate(values):
        if value == target:
            result.append(index)
    return result
Reasoning
enumerate visits every member and supplies its zero-based index.

Counterexamples and common mistakes

The counterexample uses range(len(values)-1), skipping the last list member.

The counterexample uses range(len(values)-1), skipping the last list member. Tests that place the target only in the middle may pass, so include final-position and single-element cases. A separate mistake modifies the source list while iterating and then skips or revisits elements as positions shift.

Do not patch an incomplete traversal by appending the last member afterward. State the intended iteration domain and choose one complete traversal. If a task genuinely needs a bounded prefix or neighbor pairs, derive that different boundary explicitly rather than changing arithmetic until one example works.

Counterexample: a plausible but incorrect implementation

python

def matching_positions(values, target):
    result = []
    for index in range(len(values) - 1):
        if values[index] == target:
            result.append(index)
    return result
Reasoning
The exclusive range stop omits the last member here.

Independent practice: small Python task

Return one-based displayed positions instead of zero-based source indices.

Return one-based displayed positions instead of zero-based source indices. Predict one and three for the same QA, Dev, QA input. Keep the equality rule and traversal unchanged; the only change is the numbering start supplied to enumerate.

This small task helps separate a user-facing position from an internal indexing convention. Do not add one to the source index in multiple places or alter which input element is read. The returned labels should change without changing the selected members.

Step 1: Keep the same value equality test. Step 2: Start the enumeration labels at one.

Practice starter: solve before reading the solution

python

def matching_positions(values, target):
    # Return one-based displayed positions without changing membership.
    raise NotImplementedError
Reasoning
Change only the enumeration start for the display contract.
  • Hint 1: enumerate accepts a start argument.
  • Hint 2: Do not change the underlying source lookup or skip an endpoint.

Solution, tests and trade-offs

The solution starts enumerate at one and appends those displayed positions.

The solution starts enumerate at one and appends those displayed positions. It handles first, final, repeated, absent and empty cases consistently. The input list is checked for preservation because output positions should describe the original population, not a list modified during traversal.

Acceptance compares the full ordered position list. A weak check that tests only its length could accept correct counts attached to wrong positions. For a single matching element the result is one under this revised contract, not zero and not an empty list.

Practice solution and acceptance checks

python

def matching_positions(values, target):
    result = []
    for position, value in enumerate(values, start=1):
        if value == target:
            result.append(position)
    return result
Reasoning
Selected members are unchanged while their position labels become one-based.

Interview reasoning and next step

In an interview, explain the iteration domain and stopping condition before discussing syntax.

In an interview, explain the iteration domain and stopping condition before discussing syntax. Use empty and single-element inputs to expose off-by-one errors. Distinguish a zero-based index, a one-based label and a count; they can share numeric values without representing the same concept.

The following function lesson examines argument defaults and return contracts. It uses repeated calls as another kind of sequence, where a shared mutable default can make a later call depend on earlier work unexpectedly.

Optional stretch — after the core task works: Derive a neighbor-pair traversal and test both empty and single-element inputs before extending it.

Computer practice: https://applydjinn.com/typorithm/python-lab-20261105.zip. Run verify.py with your selected Python interpreter, then complete an exercise and check it with --practice followed by the lesson id. The lab uses only the standard library and disposable local fixtures; it never connects to the production database or company feeds.

Visit each intended element once and distinguish a displayed position from a source index.