Skip to main content
MahiDev — Learn. Build. Become AI-ready.

Lesson 05

Python kvrange Generator — start, stop, step, and InputError

Learn kvrange as a bus route: start, stop, step, yield on each stop, next()+for handoff, InputError ticket, and inclusive stop vs range().

Intermediate40 min

kvrange bus journey start stop step hero` inclusive

  • Three-argument start, stop, step, keyword args, custom InputError
  • After some next() calls, a for loop continues from the remaining values
  • The first next() on kvrange(0, 0, 0) raises InputError (generator body runs on first iteration)
  • kvrange is inclusive of stop (unlike builtin range())

The generator

python
class InputError(Exception):
    pass

def kvrange(start=0, stop=0, step=1):
    if (start == stop) and (stop == step):
        raise InputError
    if start >= stop:
        stop = start
        start = 0
    while start <= stop:
        yield start
        start = start + step

Think of it like this

![kvrange loop Start yield Move yield Repeat until stop](data:image/svg+xml;charset=utf-8,%3Csvg%20font-family%3D%27ui-sans-serif%2C-apple-system%2Csystem-ui%2CArial%27%20width%3D%27100%25%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%20320%20180%27%3E%20%3Crect%20width%3D%27320%27%20height%3D%27180%27%20rx%3D%2714%27%20fill%3D%27%23ECFDF5%27%2F%3E%20%3Crect%20x%3D%2760%27%20y%3D%2712%27%20width%3D%27200%27%20height%3D%2722%27%20rx%3D%276%27%20fill%3D%27%23A7F3D0%27%2F%3E%20%3Ctext%20x%3D%2772%27%20y%3D%2727%27%20font-size%3D%278%27%20font-weight%3D%27bold%27%20fill%3D%27%23065F46%27%3EStart%3C%2Ftext%3E%20%3Ctext%20x%3D%27248%27%20y%3D%2727%27%20font-size%3D%278%27%20text-anchor%3D%27end%27%20fill%3D%27%23047857%27%3E10%3C%2Ftext%3E%20%3Crect%20x%3D%2760%27%20y%3D%2744%27%20width%3D%27200%27%20height%3D%2722%27%20rx%3D%276%27%20fill%3D%27%23A7F3D0%27%2F%3E%20%3Ctext%20x%3D%2772%27%20y%3D%2759%27%20font-size%3D%278%27%20font-weight%3D%27bold%27%20fill%3D%27%23065F46%27%3Eyield%3C%2Ftext%3E%20%3Ctext%20x%3D%27248%27%20y%3D%2759%27%20font-size%3D%278%27%20text-anchor%3D%27end%27%20fill%3D%27%23047857%27%3E10%3C%2Ftext%3E%20%3Crect%20x%3D%2760%27%20y%3D%2776%27%20width%3D%27200%27%20height%3D%2722%27%20rx%3D%276%27%20fill%3D%27%23A7F3D0%27%2F%3E%20%3Ctext%20x%3D%2772%27%20y%3D%2791%27%20font-size%3D%278%27%20font-weight%3D%27bold%27%20fill%3D%27%23065F46%27%3EMove%3C%2Ftext%3E%20%3Ctext%20x%3D%27248%27%20y%3D%2791%27%20font-size%3D%278%27%20text-anchor%3D%27end%27%20fill%3D%27%23047857%27%3E10%20%2B%202%3C%2Ftext%3E%20%3Crect%20x%3D%2760%27%20y%3D%27108%27%20width%3D%27200%27%20height%3D%2722%27%20rx%3D%276%27%20fill%3D%27%23A7F3D0%27%2F%3E%20%3Ctext%20x%3D%2772%27%20y%3D%27123%27%20font-size%3D%278%27%20font-weight%3D%27bold%27%20fill%3D%27%23065F46%27%3Eyield%3C%2Ftext%3E%20%3Ctext%20x%3D%27248%27%20y%3D%27123%27%20font-size%3D%278%27%20text-anchor%3D%27end%27%20fill%3D%27%23047857%27%3E12%3C%2Ftext%3E%20%3Crect%20x%3D%2760%27%20y%3D%27140%27%20width%3D%27200%27%20height%3D%2722%27%20rx%3D%276%27%20fill%3D%27%23A7F3D0%27%2F%3E%20%3Ctext%20x%3D%2772%27%20y%3D%27155%27%20font-size%3D%278%27%20font-weight%3D%27bold%27%20fill%3D%27%23065F46%27%3ERepeat%3C%2Ftext%3E%20%3Ctext%20x%3D%27248%27%20y%3D%27155%27%20font-size%3D%278%27%20text-anchor%3D%27end%27%20fill%3D%27%23047857%27%3EUntil%2020%3C%2Ftext%3E%20%3C%2Fsvg%3E

Each yield pauses the function until next() is called again.

Try different routes in the playground

Change start, stop, and step in the playground below and watch the route change. Example: Start 10, Stop 20, Step 2.

kvrange 10 20 2 generated route number line` below).

How next() and for work together

You can consume two values with next(), then let a for loop continue from the remaining values.

next consumed 10 12 for loop continues 14 through 20

print(next(r)) # 10 print(next(r)) # 12

for value in r: print(value)

14 16 18 20

code

The two-argument form uses the same idea: two `next(r1)` calls, then `for val in r1` prints the rest. A further `next(r1)` raises **`StopIteration`**.

## Two-argument kvrange

```python
def kvrange(beg, end):
    while beg <= end:
        yield beg
        beg = beg + 1

r = kvrange(10, 20)
print(next(r))
while True:
    try:
        print(next(r))
    except StopIteration:
        break

Different ways to call kvrange

1. kvrange(10, 20, 2)

Bus starts at 10 and jumps 2 stops.

kvrange 10 20 2 bus every two stops`

When start=5 >= stop=0, the logic converts this to 0 → 5.

kvrange 5 single arg depot zero to five`

Keyword arguments make the route clearer.

kvrange stop 6 step 2 keyword route| Bus from 10 to 20, every 2 stops | |kvrange(5)| Start from depot (0) to Stop 5 | |kvrange(stop=6, step=2)` | Go to 6 using every second stop |

Other useful calls: kvrange(100, 120, 5), kvrange(25, 30) with default step 1.

Run the full script in the playground below.

InputError = invalid ticket

If someone gives the driver this ticket:

  • Start = 0
  • Stop = 0
  • Step = 0

There is nowhere to go.

![InputError invalid ticket start stop step all zero](data:image/svg+xml;charset=utf-8,%3Csvg%20font-family%3D%27ui-sans-serif%2C-apple-system%2Csystem-ui%2CArial%27%20width%3D%27100%25%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%20320%2090%27%3E%20%3Crect%20width%3D%27320%27%20height%3D%2790%27%20rx%3D%2712%27%20fill%3D%27%23FEF2F2%27%2F%3E%20%3Crect%20x%3D%2740%27%20y%3D%2720%27%20width%3D%27240%27%20height%3D%2750%27%20rx%3D%278%27%20fill%3D%27%23FEE2E2%27%20stroke%3D%27%23DC2626%27%20stroke-dasharray%3D%274%204%27%2F%3E%20%3Ctext%20x%3D%27160%27%20y%3D%2738%27%20font-size%3D%279%27%20font-weight%3D%27bold%27%20text-anchor%3D%27middle%27%20fill%3D%27%23991B1B%27%3EInvalid%20ticket%3C%2Ftext%3E%20%3Ctext%20x%3D%27160%27%20y%3D%2752%27%20font-size%3D%278%27%20text-anchor%3D%27middle%27%20fill%3D%27%237F1D1D%27%3Estart%3D0%20stop%3D0%20step%3D0%3C%2Ftext%3E%20%3Ctext%20x%3D%27160%27%20y%3D%2766%27%20font-size%3D%278%27%20text-anchor%3D%27middle%27%20fill%3D%27%23991B1B%27%3EInputError%20on%20next%28%29%3C%2Ftext%3E%20%3C%2Fsvg%3E

python
class InputError(Exception):
    pass

if (start == stop) and (stop == step):
    raise InputError

Handling it:

python
try:
    r5 = kvrange(0, 0, 0)
    print(next(r5))
except InputError:
    print("Check Start, stop and step Values:")

Calling kvrange(0, 0, 0) only creates the generator object. The exception appears when next() starts executing the body.

Built-in range() vs kvrange()

range stops before 20 kvrange includes final stop inclusive| No — stops before destination | |kvrange(10, 20, 2)| Yes —while start <= stop` |

Python range(10, 21, 2) gives 10, 12, 14, 16, 18 (no 20). kvrange(10, 20, 2) includes the final stop 20.

Interview cheat sheet

Topic Answer
Keyword yield
Inclusive? Yes, <= stop
Empty / zeros InputError on first next()
Partial consume for continues after next()
vs range() kvrange includes stop

30-second recap

kvrange Start yield Step Repeat Stop recap flow.

Loading playground…

Check your understanding

kvrange generator quiz

kvrange(beg, end) with two arguments is:

1 / 10