How does the range( ) function work?

Question

How does the range( ) function work?

Answer

The range() function’s three different versions give us all kinds of options for generating ranges of numbers.

  1. range(stop) generates a range of numbers from 0 up to the stop point. It does not include the stop number. So writing range(3) gives us [0, 1, 2]. 3 is not included.
  2. range(start, stop) does the same thing, but now we can specify a starting value. The stop is still not included, but start is included. If we have range(0, 3), it produces the same result as above. This is useful when we don’t want to start at 0, though!
  3. range(start, stop, step) works mostly like the above, where start is included, stop is excluded, and now we have another parameter to work with: step. This step tells it by how much to change in value each time. For example, writing range(0, 10, 2) give us [0, 2, 4, 6, 8] because we started at 0, stopped at 10 (not included), and stepped by 2 each time.
6 Likes

Hi,

Nothing major but I want to know how the range() function works inside the my_function(). I have read back on my notes and it seems that Len(x) effectively means how many items are in the list. Surely, then, this would mean that the console should give the numbers 0 to 3 since the length of the list produced by the range(3) is 3?

Cheers
Josh

1 Like

we have no idea what my_function looks like or to what exercise its related. Please share such information

if we look at the FAQ:

it should perfectly answer your question? I mean, even the values are an exact match.

2 Likes

Yep, it does! Thanks so much!

1 Like

This doesn’t compile (I used the solution)?

Passing a range into a function\script.py", line 3, in my_function
x[i] = x[i]
TypeError: ‘range’ object does not support item assignment

line 6, you might want to change:

range(3)

to:

list(range(3))

this way, you have a list. range() does not give a list in python3

There is something i dont understand here:

def my_function(x):
for i in range(0, len(x)):
x[i] = x[i]
return x

if len(x) is for example 3 then it would be range(0, 3)
now if your list of numbers is [3, 4, 5] then nothing is going to be printed because it stops before 3. so why do we use len(x) in this function?

We must not confuse the data with the index.

 0  1  2  <= indices (data points)
[3, 4, 5]
  \  \  \
 data values

The value at index[3] does not exist since that data point does not exist.

Because that will give us an upper bound (highest existing index). range works similar to above. The length is 3, but index[3] does not exist so it is dropped from the sequence.

 range(0, len(x))

as a list it will read, [0, 1, 2] which corresponds with our illustration above.

There are two ways to iterate a list.

  • by direct access to the values
    for value in x:
        print (value)
  • by indexed access
    r = range(len(x))
    for i in r:
        print (x[i])
3 Likes
y=(2,4,5,6,7,9)

def my_function(y):
  for i in range(0, len(y)):
    y[i] = y[i]
  return y

print my_function(range(0,6,2))

So, I am not understanding the step part of the range function.
When I run the above code it prints [0, 2, 4]
In the exercise the description of step is “Each item increases by step.”
In which case I would think it means that either:

a) The value of the number at each indices increases by the value of “step”

  • So I would expect it to print [4, 6, 7, 8, 9, 11]
    or
    b) The value returned would be the value at each original indices and the “step” would refer to skipped indices (Sorry,I did not word this part well)
  • So I would expect it to print [2, 5, 7]

These are both obviously very wrong. If someone could please clarify I would greatly appreciate it.

From the documentation,

The arguments to the range constructor must be integers (either built-in int or any object that implements the index() special method). If the step argument is omitted, it defaults to 1. If the start argument is omitted, it defaults to 0. If step is zero, ValueError is raised.

# Start at 0, stop before 10, Step size omitted so default step size: 1
for i in range(0, 10):
    print(i)
# Output: 0 1 2 3 4 5 6 7 8 9 (printed on separate lines)

# Start omitted, so default start: 0, stop before 10, 
# Step size omitted so default step size: 1
for i in range(10):
    print(i)
# Output: 0 1 2 3 4 5 6 7 8 9 

# Start at 0, Stop before 10, Step size: 2
for i in range(0, 10, 2):
    print(i)
# Output: 0 2 4 6 8 

# Start at 0, Stop before 10, Step size: 3
for i in range(0, 10, 3):
    print(i)
# Output: 0 3 6 9

In the snippet you posted, the variable y outside the function and the parameter y of the function have different scope and don’t refer to the same thing (even though they are both named y). The parameter y of my_function is local to the function whereas y=(2,4,5,6,7,9) is a tuple at the global scope.
Basically, the parameter y in def my_function(y) says that whatever input/data(argument) is passed to the function, we are going to assign it to a a variable named y. Within the body of the function, we are going to manipulate/use the input by using the variable y. We don’t care about what the input is named outside the function. This abstraction allows us to pass different inputs to the function without need of editing the function.

# y =  (2,4,5,6,7,9) will also work.
# I am just using x to avoid confusion  
x = (2,4,5,6,7,9)

def my_function(y):
    for i in range(0, len(y), 2):
        print(y[i])

# Function call with x being passed as the argument.
my_function(x)  
#########################
# Output: 2 5 7 (on separate lines)
#########################

# Within the function, the input x = (2,4,5,6,7,9) will be 
# assigned to the parameter y.
# In the body of the function, y will refer to the input 
# regardless of the fact that it is named x outside the function.
# Since step size of 2 was specified, so the 0th, 2nd and 4th elements 
# will be printed i.e. 2, 5 and 7 will be printed.
# (Outside the function, instead of x we could have used y as the variable name
# i.e. y  = (2,4,5,6,7,9) in which case we would make the function call
# my_function(y). Within the function, we will assign this tuple to the 
# parameter (local to the function) named 'y'. The input can be named 
# x,y, myVar, whatever outside the function. But, once the input is passed
# to the function, it will be assigned to the parameter y)

In the snippet you posted, you made the function call

my_function(range(0,6,2))

You are passing the sequence 0, 2, 4 as the input to my_function. In the function, this sequence will be assigned to the parameter y. Within the body of the function, whenever you use y in your code, it will refer to the input sequence, not to the global variable.

2 Likes

Thank you for the very detailed explanation!