How to loop over a Python range that has a single item - zero length range

I’m working on an app that accepts user input of a start year and end year, loops through those years, and outputs the year.

For example, given the start year and end year of 2020, I want a loop to execute for 2020.

years = range(2020, 2020)
for y in years:
    print(y)

But the python range object doesn’t recognize this as a single range item and won’t output anything. The source for the range object is here: https://github.com/python/cpython/blob/master/Objects/rangeobject.c and I believe it is this conditional statement that causes range to return a length of zero.

/* if (lo >= hi), return length of 0. */
cmp_result = PyObject_RichCompareBool(lo, hi, Py_GE);
if (cmp_result != 0) {
    Py_DECREF(step);
    if (cmp_result < 0)
        return NULL;
    return PyLong_FromLong(0);
&#125;

As Amy mentions in the comments below, this is because the stop parameter of the range object is exclusive - meaning it does a < compare, not a <= compare. So a great option is to always just add 1 to the stop parameter to include it.

def lte_range_plusone(start, stop, step=1):
    return range(start, stop + 1, step)

An alternate solution to this was to create a custom function that uses the python yield keyword to return an item even if the start and end are equal, with this code:

def lte_range_yield(start, stop, step=1):
    while start <= stop:
        yield start
        start += step

This code will yield aka return the start value even if it is equal to the end value.

So, this code:

years = lte_range_yield(2020, 2020)
for y in years:
    print(y)

Will output:

2020

Hope this helps you out. Let me know in the comments if you know of a better way to achieve this.

Thanks,
Jon