Loops¶
Materials:¶
Often, programs need to do the same task several times repeatedly. You may need to run a task just a handful of times, or maybe thousands of times.
For example, say you want to print out all of the numbers 0 - 5. You
could write print()
5 times:
print(0)
print(1)
print(2)
print(3)
print(4)
print(5)
However, if you want to expand this even a few numbers further, it gets very tedious very quickly.
To save us from having to have the same code duplicated over and over,
we have loops. They are incredibly powerful tools for examining
large amounts of information. Here we will be looking at while
loops and for
loops.
while
loops¶
while
loops are somewhat similar to if
statements as both depend
on conditions to do actions. You can think of a while
loop as an
if
statement that keeps on repeating as long as the condition stays
true.
Here is an example of a basic while
loop:
i = 0 # initialize index
while i < 5: # runs 5 times
print(i)
i += 1 # increment i
0
1
2
3
4
Let’s break down the code.
i = 0
: We initializei
as 0 before thewhile
loopwhile i < 5:
: This begins thewhile
loop and specifies the condition being tested. Essentially it means as long asi
is less than 5, keep doing the code below.print(i)
: Print current value ofi
i += 1
: We increase the value ofi
at the end of each loopOnce
i += 1
runs, thewhile
loop checks the current value ofi
If
i
is less than 5, the code in thewhile
loop runs again. Otherwise, the loop is over.
We have to be careful not to create an infinite loop. For instance, if
you removed the line with i += 1
, i
would never reach 5, and the
loop would keep printing 0
. If you do this, you can always halt
execution of the cell.
Below is more complicated while
loop. We have a list of names, and
an index i
keeping track of where we are in the list. We want to
print out names until we reach 'Jimmy'
, so we keep a boolean
variable called notJimmy
set to True
initially. We go through
the list one name at a time and check to see if the name is 'Jimmy'
.
If the name is 'Jimmy'
, we change notJimmy
to be False
;
otherwise, we don’t do anything. Regardless, we continue to the end of
the loop, printing the name and the value of notJimmy
and
incrementing i
by one. If not Jimmy
is true, the loop keeps
going; otherwise, it is finished.
friends = ['Jim', 'Bob', 'Jimbob', 'Jimmy', 'James'] # list of friend names
notJimmy = True # initialize condition as True
i = 0 # initialize index i as 0
while notJimmy: # while notJimmy is True
friend = friends[i] # select one of the friend names
if friend == 'Jimmy': # if the friend name is Jimmy
notJimmy = False # change notJimmy to be false
print(friend, ',', notJimmy) # print each name and also the val of not Jimmy
i += 1 # increment i
Jim , True
Bob , True
Jimbob , True
Jimmy , False
Question 1: while
loops:¶
Create a variable x
with the value of 8. Divide x
by 2 and
re-assign this value to x
. Continue to do this until x
is less
than 0.00001. Print out how many divisions this takes.
### your code here:
Solution
x = 8
i += 1
while x >= 0.00001:
x /= 2
i += 1
print(i)
20
for
loops¶
for
loops are one of the most powerful tools that base Python has to
offer. for
loops take iterables (lists, dictionaries, sets,
tuples, even strings) and perform the same actions to each item
contained within them.
In the code below, each number in a list gets added to 20, and then the
sum is printed. We call this iterating over the items in the list.
Note the keywords for
and in
.
num_list = [0, 1, 2, 3, 4, 5] # list of numbers
for n in num_list: # one at a time, make each of those numbers n
print(n + 20) # print that number + 20
20
21
22
23
24
25
Let’s break down this code:
num_list = [0, 1, 2, 3, 4, 5]
: Makes a list of integers 0-5.for n in num_list:
: Take the first item in num_list and assign its value ton
.print(n + 20)
: Add n and 20 and print the sum.We then go back to the start of the loop, take the next item, assign it to
n
, and start all over again.
For ordered iterables, like lists, tuples, and strings, for
loops
iterate over these groups in order.
Just like normal variable names, the variable name we use after for
is arbitrary, though short and descriptive is best.
for triangle in num_list: # 0 is not a triangle
print(triangle)
0
1
2
3
4
5
If you want to quickly create a range of numbers to iterate over, the
range()
function generates numbers from 0 to the int you provide
(but not including it).
for i in range(4): # includes 0, but not 4
print(i)
0
1
2
3
We can start to use for loops to do tasks with strings, as well.
my_breakfast = ['eggs', 'cereal', 'oatmeal', 'toast']
for food in my_breakfast: # for each string in the list of string
sentence = 'I like to eat ' + food + '.'
print(sentence)
I like to eat eggs.
I like to eat cereal.
I like to eat oatmeal.
I like to eat toast.
We can use the enumerate()
function to iterate over items in a list
and get their indexes at the same time.
When use use enumerate()
, we need to provide two variables names
separated by a comma. The first represents the current index, and the
second is the item at that index.
for i, food in enumerate(my_breakfast):
print('index:', i)
print('food:', food)
index: 0
food: eggs
index: 1
food: cereal
index: 2
food: oatmeal
index: 3
food: toast
This is a very useful approach for iterating over multiple lists of the same length at once.
my_lunch = ['sandwich', 'chips', 'fruit', 'juice']
my_dinner = ['pasta', 'salad', 'bread', 'dessert']
for i, breakfast in enumerate(my_breakfast):
lunch = my_lunch[i]
dinner = my_dinner[i]
print("my food today:", breakfast, lunch, dinner, i)
my food today: eggs sandwich pasta 0
my food today: cereal chips salad 1
my food today: oatmeal fruit bread 2
my food today: toast juice dessert 3
Question 2: Looping with indexes¶
Below are four lists: x1
, x2
, y1
, and y2
.
Using a single for loop, subtract the values of x1 and x2 at each index,
and take the square of the difference. Do the same for y1
and
y2
. Add the two squares together. Store all 4 squares in a list in
the same order.
x1 = [6.3, 7.1, 3.7, 3.2, 0.1]
x2 = [-5.7, -17.5, -3.2, -19.3,-18.2]
y1 = [34.6, 28.4, 60.0, 68.1, 83.9]
y2 = [188.7, 75.9, 100.1, 61.1, 180.2]
# your code here:
Solution
vals = list()
for i, x_1 in x1:
x_2 = x2[i]
y_1 = y1[i]
y_2 = y2[i]
val = (x_1 - x_2)**2 + (y_1 - y_2)**2
vals.append(val)
Adding in conditionals¶
for
loops can become quite powerful when you include conditionals
that change behavior based on the item in the current iteration.
for food in my_breakfast:
if food == 'eggs': # if food is currently 'eggs'
sentence = 'I do not like to eat ' + food + '.'
else: # for all other values of food
sentence = 'I like to eat ' + food + '.'
print(sentence)
I do not like to eat eggs.
I like to eat cereal.
I like to eat oatmeal.
I like to eat toast.
We can even use full if
-elif
-else
statements.
for food in my_breakfast:
if len(food) < 5: # if the length of string is less than 5
sentence = 'I do not like to eat ' + food + '.'
elif len(food) < 6: # if the length is 5
sentence = 'I sometimes like to eat ' + food + '.'
else: # if the length is greater than 5
sentence = 'I like to eat ' + food + '.'
print(sentence)
I do not like to eat eggs.
I like to eat cereal.
I like to eat oatmeal.
I sometimes like to eat toast.
Question 3: More loops¶
Iterate over all integers from 0 to 1000 and print all multiples of 41 (numbers that can be divided by 41 with no remainder). How many multiples are there?
### put your code below:
Solution
i = 0 # counts the number of multiples
for n in range(1000):
if n % 41 == 0: #if the remainder is 0
print(n)
i += 1
print('number of multiples:', i)
0
41
82
123
164
205
246
287
328
369
410
451
492
533
574
615
656
697
738
779
820
861
902
943
984
number of multiples: 25
Nested for loops
Just like you can use if
statements in a for
loop, you can also
put for
loops inside of other for
loops. This is great if you
want to use all combinations of two lists, for instance.
hats = ['bowler', 'fedora', 'beret']
shirts = ['plaid', 'striped', 'polka dot']
print('Outfit combinations:')
for shirt in shirts:
for hat in hats:
print(shirt, "shirt with a", hat)
Outfit combinations:
plaid shirt with a bowler
plaid shirt with a fedora
plaid shirt with a beret
striped shirt with a bowler
striped shirt with a fedora
striped shirt with a beret
polka dot shirt with a bowler
polka dot shirt with a fedora
polka dot shirt with a beret
Be careful, however. If you use very long collections of items and nest more than 2 loops, the runtime can become very slow.
Comprehensions
If the outcome of your for
loop is to produce a list, dictionary,
set, or tuple, and you are using minimal code in your loop, then
comprehensions may be perfect for you.
[ food + ' time' for food in my_breakfast ] # creates a list
['eggs time', 'cereal time', 'oatmeal time', 'toast time']
{ food:len(food) for food in my_breakfast } # creates a dictionary
{'eggs': 4, 'cereal': 6, 'oatmeal': 7, 'toast': 5}