- For loops
- When do I use for loops
- How do they work?
- Nested loops
- Examples
- A note on `range`
- More resources
- for Loops#
- A for loop executes commands once for each value in a collection#
- A for loop is made up of a collection, a loop variable, and a body.#
- The first line of the for loop must end with a colon, and the body must be indented#
- Indentation is always meaningful in Python#
- Question#
- Solution#
- Loop variables can be called anything.#
- The collection can be a list, dictionary, etc. that was defined previously#
- The body of a loop can contain many statements.#
- Use range to iterate over a sequence of numbers#
- The “accumulator” pattern turns many values into one#
- Accumulators can also be empty lists#
- List comprehension#
- Lambda Functions and Mapping#
- Mapping#
For loops
There are two ways to create loops in Python: with the for-loop and the while-loop.
When do I use for loops
for loops are used when you have a block of code which you want to repeat a fixed number of times. The for-loop is always used in combination with an iterable object, like a list or a range. The Python for statement iterates over the members of a sequence in order, executing the block each time. Contrast the for statement with the »while» loop, used when a condition needs to be checked each iteration or to repeat a block of code forever. For example:
For loop from 0 to 2, therefore running 3 times.
for x in range(0, 3): print("We're on time %d" % (x))
While loop from 1 to infinity, therefore running forever.
x = 1 while True: print("To infinity and beyond! We're getting close, on %d now!" % (x)) x += 1
When running the above example, you can stop the program by pressing ctrl+c at the same time. As you can see, these loop constructs serve different purposes. The for loop runs for a fixed amount of times, while the while loop runs until the loop condition changes. In this example, the condition is the boolean True which will never change, so it will run forever.
How do they work?
If you’ve done any programming before, you have undoubtedly come across a for loop or an equivalent to it. Many languages have conditions in the syntax of their for loop, such as a relational expression to determine if the loop is done, and an increment expression to determine the next loop value. In Python, this is controlled instead by generating the appropriate sequence. Basically, any object with an iterable method can be used in a for loop. Even strings, despite not having an iterable method — but we’ll not get on to that here. Having an iterable method basically means that the data can be presented in list form, where there are multiple values in an orderly fashion. You can define your own iterables by creating an object with next() and iter() methods. This means that you’ll rarely be dealing with raw numbers when it comes to for loops in Python — great for just about anyone!
Nested loops
When you have a block of code you want to run x number of times, then a block of code within that code which you want to run y number of times, you use what is known as a «nested loop». In Python, these are heavily used whenever someone has a list of lists — an iterable object within an iterable object.
for x in range(1, 11): for y in range(1, 11): print('%d * %d = %d' % (x, y, x*y))
Like the while loop, the for loop can be made to exit before the given object is finished. This is done using the break statement, which will immediately drop out of the loop and continue execution at the first statement after the block. You can also have an optional else clause, which will run should the for loop exit cleanly — that is, without breaking.
for x in range(3): if x == 1: break
Examples
for x in range(3): print(x) else: print('Final x = %d' % (x))
string = "Hello World" for x in string: print(x)
collection = ['hey', 5, 'd'] for x in collection: print(x)
list_of_lists = [ [1, 2, 3], [4, 5, 6], [7, 8, 9]] for list in list_of_lists: for x in list: print(x)
Creating your own iterable
class Iterable(object): def __init__(self,values): self.values = values self.location = 0 def __iter__(self): return self def next(self): if self.location == len(self.values): raise StopIteration value = self.values[self.location] self.location += 1 return value
Your own range generator using yield
def my_range(start, end, step): while start yield start start += step for x in my_range(1, 10, 0.5): print(x)
A note on `range`
The »range» function is seen so often in for statements that you might think range is part of the for syntax. It is not: it is a Python built-in function that returns a sequence following a specific pattern (most often sequential integers), which thus meets the requirement of providing a sequence for the for statement to iterate over. Since for can operate directly on sequences, there is often no need to count. This is a common beginner construct (if they are coming from another language with different loop syntax):
mylist = ['a', 'b', 'c', 'd'] for i in range(len(mylist)): # do something with mylist[i]
It can be replaced with this:
mylist = ['a', 'b', 'c', 'd'] for v in mylist: # do something with v
Consider for var in range(len(something)): to be a flag for possibly non-optimal Python coding.
More resources
ForLoop (last edited 2022-01-23 09:18:40 by eriky )
for Loops#
A for loop executes commands once for each value in a collection#
- Doing calculations on the values in a list one by one is as painful as working with many individual variables rather than a list or dictionary (e.g., life_exp_1900 , life_exp_1920 , etc. rather than life_exp = [48.1, 56.6, 64.0, 71.0, 75.2, 79.2]
- A for loop tells Python to execute some statements once for each value in a list, a character string, or some other collection
- The for command means, “for each thing in this group, do these operations”
for number in [2, 3, 5]: print(number)
The for loop above is equivalent to:
and the for loop’s output is:
for number in [2, 3, 5]: print(number)
- However, the for loop is scalable to any length input.
- This makes it flexible, because we might not know in advance how many inputs we want to operate on.
A for loop is made up of a collection, a loop variable, and a body.#
for number in [2, 3, 5]: print(number)
- The collection, [2, 3, 5] , is what the loop is being run on.
- The loop variable, number , is what changes for each iteration of the loop.
- This keeps track of where we are in the loop — the “current thing”
The first line of the for loop must end with a colon, and the body must be indented#
- The colon at the end of the first line signals the start of a block of statements.
- Python uses indentation to show nesting (this is different from other languages, which often use explicit markers for the start and end (e.g., <> or begin / end ) of a nesting.
- Any consistent indentation is legal, but almost everyone uses four spaces.
for number in [2, 3, 5]: print(number)
Indentation is always meaningful in Python#
- After a for statement, Python expects at least one indented line with teh body of the for loop
- The end of the body of a for loop is indicated by a line of code that is not indented
- It’s good coding style (although not required) to put a blank line after the end of the body of a for loop, before the next line of code that’s not in the for loop
for country in ['Canada', 'USA', 'Mexico']: print(country) print('All done printing country names')
Canada USA Mexico All done printing country names
life_exp_1900 = 48.1 life_exp_1920 = 56.6
life_exp_1900 = 48.1 life_exp_1920 = 56.6
Cell In [3], line 2 life_exp_1920 = 56.6 ^ IndentationError: unexpected indent
This error can be fixed by removing the extra spaces at the beginning of the second line.
life_exp_1900 = 48.1 life_exp_1920 = 56.6
Question#
Is an indentation error a syntax error or a runtime error?
Solution#
A Python IndentationError is a syntax error. Programs with syntax errors cannot be started. A program with a runtime error will start but an error will be thrown under certain conditions.
Loop variables can be called anything.#
As with all variables, loop variables are:
- Created on demand
- Meaningless: their names can be anything at all
- So the following are valid for loops, but not great loop variable names (unless in the first example your data actually concern kittens):
for kitten in [2, 3, 5]: print(kitten)
for ytrjmn in [2, 3, 5]: print(ytrjmn)
The collection can be a list, dictionary, etc. that was defined previously#
life_exp = [48.1, 56.6, 64.0, 71.0, 75.2, 79.2] for e in life_exp: print(e)
- Strings can also be used as the collection, in which case the loop will step through each character of the string:
The body of a loop can contain many statements.#
primes = [2, 3, 5] for p in primes: squared = p ** 2 cubed = p ** 3 print(p, squared, cubed)
Use range to iterate over a sequence of numbers#
- This is an easy way to generate a sequence of numbers to make looping over large ranges more efficient
- range(n) is the numbers 0 … n-1
- recall that Python counts from zero
- as with slicing, range() goes up to, but does not include, the last value
- If we provide two arguments to range() , the first is the start and the second is the end of the range:
for i in range(10, 15): print(i)
- Although the range() function can substitute for typing out a list, it does not actually produce a list
- The numbers are produced on demand to make looping over large ranges more efficient. We can see this by printing the result of calling the range() function:
The “accumulator” pattern turns many values into one#
A common pattern in programs is to:
- Initialize an accumulator variable to zero
- Update the variable with values from a collection.
- The code below sums the integers 1-10:
total = 0 for number in range(1, 11): total = total + number print(total)
- Note that we specify a range of 1-11 because the range() goes up to, but does not include, the ‘end’ number
- Read total = total + number as:
- Add the value of number to the current value of the accumulator variable total .
- Assign that to total , replacing the current value.
Accumulators can also be empty lists#
This is where empty lists and the .append() method can be really useful — we can initialize an empty list and the append to it each time through the loop:
output = [] for i in range(10): output.append(i * 2) print(output)
List comprehension#
- List comprehension is a special kind of for loop that you can use to create a list
- This can be a very powerful and compact way of doing things
- For example, the following code creates a list of values from 1 to 10 in a single line of code:
- List comprehension can be very useful if you want to apply some operation to every value in a list
- For example, let’s say we had a set of times in seconds, and we wanted to convert them to milliseconds (thousandths of a second):
time_sec = [0.19859864, 1.35544082, 0.81298099, 1.80873061, 0.78908326, 1.40242708, 0.39563692, 1.91673302, 1.07524985, 1.02169021] time_ms = [t * 1000 for t in time_sec] print(time_ms)
[198.59864, 1355.44082, 812.98099, 1808.73061, 789.08326, 1402.4270800000002, 395.63692, 1916.73302, 1075.2498500000002, 1021.6902100000001]
The equivalent for loop would require three lines of code:
time_ms = [] for t in time_sec: time_ms.append(t * 1000) print(time_ms)
[198.59864, 1355.44082, 812.98099, 1808.73061, 789.08326, 1402.4270800000002, 395.63692, 1916.73302, 1075.2498500000002, 1021.6902100000001]
We can put multiple operations in a list comprehension, for example to also round our milliseconds down to whole numbers:
time_ms = [round(t * 1000) for t in time_sec] print(time_ms)
[199, 1355, 813, 1809, 789, 1402, 396, 1917, 1075, 1022]
Lambda Functions and Mapping#
Yet another way of performing an operation over a collection, is by combining map() and lambda functions. Recall that functions are Python commands like print() and type() . A Python function is actually a program that is run when you execute the function.
lambda functions are a way of creating your own very small functions, on the fly, to perform a specific operation or combination of operations. Lambda functions take variables as input and return a value (the results of the operations it performs). A lambda function is composed of:
- the statement lambda
- the argument(s) — the variable(s) you pass to the operations in the lambda function
- a colon
- the expression (operations you want the function to perform on the arguments)
For example, we-writing the above code to convert seconds to milliseconds and round to integers as a lambda function would be:
Mapping#
As with the print() or round() functions, with a lambda function you need to pass something to it as an argument for it to operate on. The variable t in the lambda function above represents the argument passed to the lambda function. We can pass a collection to a lambda function, so that it will be applied to each item in the collection.
The map() function is used to apply a lambda function to a collection, instead of using a for loop
The code below maps the convert-to-milliseconds-and-round function to the time_sec list:
time_ms = map(lambda t: round(t * 1000), time_sec)
However, the result is not a list, but a Python `map’ object:
print(type(time_ms)) print(time_ms)