For Loops in Python

einbahnstrasse.github.io/MTEC1003-slides/slides/python.for.loop.tutorial.v01/

MTEC1003 — Media Computation Skills Lab

In this tutorial, we’ll discuss…

Iteration + Collection,

Lists vs. Dictionaries

Python Methods

Arithmetic Series

and For Loops

…but in Python, NOT JavaScript!…

What is Iteration?

Simply put, iteration is the process of repeating a set of instructions until some condition is met.

“Why use a Loop?”

Repetitive tasks take time to code, so it’s much more efficient to write a loop. With a loop we can:

tell the computer to repeat similar tasks many times,

save valuable time typing endless lines of code,

and also very important…

by forcing ourselves to think carefully about the “rules”
we create to govern our loops,

we clarify what we want to accomplish

and avoid making the careless mistakes
that occur when we type by hand!

What is Iteration used for?

Think of what we can accomplish with iterative processes…

rapidly generate long lists of numbers

periodically check on the value of some variable

count through the items in a list

search for a string in each line of a text file

Can you think of some others?

Iterate + Collect

Imagine we have a list of numbers:

var myList = [1, 3, 7, 5, 4, 2, -3, -9];

Let’s say we want to
add a value of 2 to each number in the list…

With a for loop, we can execute an iterative process to count through and perform the same operation(s) on each list item, like adding a constant to each number.

Our first task would be to be to iterate over the contents of the list, counting through each item while performing the same set of actions.

1 + 2;
3 + 2;
7 + 2;
5 + 2;
... etc. ...

But we still need to collect the result into a new list:

var myNewList = [3, 5, 9, 7, 6, 4, -1, -7];

The process by which we create a new list
after we iterate over our data is called collection.

We’ll discuss how collection is done soon.
First, let’s examine further the for loop structure.

For Loop Structure

Let’s recall
the general structure of a For Loop in JavaScript,
which you learned in the 1st set of slides.

What were the 3 main components of a For Loop?

1. initialization

2. termination condition

3. increment

And what would each of those pieces look like in JavaScript?

Initialization

for (var x = 0; ........; ........) {
  [Do things expressed by the statements written here each time.];  
  }

What does the initialization part do?

It tells us how to begin,

typically starting with an index variable (e.g. var x),

set to a certain value (e.g. var x = 0)

Termination Condition

for (........; x <= 5; ........) {
  [Do things expressed by the statements written here each time.];  
  }

What does the termination condition do?

It tells us how the loop will end,

typically when the index reaches a threshold.

This loop will terminate when x reaches 5.

Increment

for (........; ........; x = x + 1) {
  [Do things expressed by the statements written here each time.];  
  }

What does the increment do?

It shows us how our process continues,
or how we step through our loop.

It tells us how much we add to x each time.

Here, we add 1 to x each time we cycle through the loop,
until it reaches our termination goal.

Now, let’s see how these

Same Three Components

are written in Python…

In Python

for x in range(0, 5):
    [Do things expressed by the statements written here each time.]

Before I break this down for you,
can you tell what the syntax is doing?

Do you see all 3 elements?

Is anything missing……??

In Python, the

Initialization

is made by first typing

for

then the 1st argument to range()
defines the initial value of our index variable x.

This initial value is 0.

Let’s see that again on the “instant replay”…

for x in range(0, 5):
    [Do things expressed by the statements written here each time.]

for initializes the loop structure.

We create variable x for indexing.

And yes indeed, the 1st argument to range() is 0,
and that’s where our indexing begins.

Termination Condition

We know the loop will be finished when x reaches 5…

because the value 5 is given as the
2nd argument to range().

Let’s see that again on the “instant replay”…

for x in range(0, 5):
    [Do things expressed by the statements written here each time.]

Yes indeed, the 2nd argument to range() is 5,
and that’s where our indexing ends.

But how do we know what the

Increment

will be??

for x in range(0, 5):
    [Do things expressed by the statements written here each time.]

Where is our x = x + 1 statement,
like in JavaScript?

If you guessed that there is currently
nothing in our Python code
that appears to designate the increment,

then you guessed correctly…

In this particular format, the increment is given
with a 3rd argument to range():

for x in range(0, 5, 2):
    [Do things expressed by the statements written here each time.]

The arguments to range() are 0, 5, and 2.

Here, the 3rd argument is 2.

This means “go from 0 to 5, but increment 2 at a time.”

Our output will be: 0, 2, and 4. (5 will be omitted.)

Range()

In our original code, we did not have
a 3rd argument for range()
but we could have…

There are 3 possible arguments:

range(color: #, [stop], [step])

Argument #1 or [start] is the initial value. This argument is optional and if no value is given, the default will be 0.

Argument #2 or [stop] is the terminating value. This one is NOT optional and, if only 1 argument is given, it will be taken as the [stop] value.

Argument #3 or [step] is the incremental value. It is optional and, if no 3rd argument is given, the default will be 1.

And finally, if only 2 arguments are given,
those are taken to mean:

range([start], [stop])

So unless we provide this “hidden” 3rd argument,
we can overlook how to specify our increment or step.

This means we could just as easily have written
a shorthand version with only 1 argument!

for x in range(5):
    [Do things expressed by the statements written here each time.]

In this case, range() falls back to its default values:

There is only 1 argument, so it’s taken as [stop].
We will iterate up to 5.

We will start indexing from 0, i.e. [start]’s default value.

The default for [step] is 1, so we will count by 1s.

In this case, our output will be: 0, 1, 2, 3, and 4.

Now, let’s use this structure
to make some really simple, stupid loops…

For example (in Python):

for x in range(5):
    print(x)

I mean this one is painfully stupid.

It just prints out the numbers 0 through 4!

I mean come on, who needs this??

But, before we move on to making more useful loops,
what will our output look like?

Will it look like this?

0, 1, 2, 3, 4

If you guessed, “nope!”
then you guessed correctly…

So, why won’t it look like this?

Because we’ve done nothing to collect
the results into a new list.

What will our output look like then?

0
1
2
3
4

This represents our output at each loop cycle,
or each time.

We see the output each time
because our print() call is indented:

for x in range(5):
    print(x)

Indentation in Python works like brackets in JavaScript.

If it’s indented, it’s part of a statement inside the loop,

and it will repeat each time,

much like bracketed code in JavaScript.

Now let’s say we want to
collect our results into a new list.

So, instead of seeing the output each time,

we want to see only the final set of numbers.

For this, we need to create a list, and use a method

Using Lists + Methods

We’ll adapt our code ever so slightly…

y = []
for x in range(5):
    y.append(x)
print(y)

Now if we run this code, our output will be:

[0, 1, 2, 3, 4]

Okay that’s a LOT of change in the code. What’s going on here?

Line 1 instantiates an empty list, i.e. [ ].

Line 3 collects each element x into the list y.

Also, line 3 uses the .append() method
to collect into our list.

And line 4 prints the final collection y.

What is a Method?

On line 3, the statement

y.append(x)

tells us to append new data to the list
that we’ve attached to variable y

The argument to y.append()
is our index variable x

So we are appending the list y with the current value of x.

We do this each time the loop cycles through.

We call .append() a method of y.

A method is a function that belongs to an object.

y is a list, and there are functions
that “belong” to Python lists…

These include .append(), .insert(), .remove(), .sort(),
and other common list processing operations.

How do we know print() will run at the end?

y = []
for x in range(5):
    y.append(x)
print(y)

Line 4 is not indented like line 3.

This means line 4 is not inside the loop structure
and therefore runs after the loop finishes.

Line 4 is executed after the loop is finished.

It therefore prints the current state of the list y

after the loop stops collecting into it.

Iterating Over a List

Say you have this list:

myShoppingList = ["soap", "video games", "hand sanitizer", "eggs", "masks"]

In this case, a list comprised of strings

How would we iterate each item, one at a time?

In JavaScript, we could do this:

var myShoppingList = ["soap", "video games", "hand sanitizer", "eggs", "masks"];
for (var i = 0; i < myShoppingList.length; i = i + 1) {
  console.log(myShoppingList[i]);
  }

And our output would be:

soap
video games
hand sanitizer
eggs
masks

exactly what we want:
an iterated list of shopping items.

This works because we did 2 new things:

1. We used .length to give us
the number of items in myShoppingList, and

2. We used myShoppingList[i]
to process each item in our list.

myShoppingList[i]

Each time the loop cycles, we use our index i
to reference and print the ith place in our list.

To do the same thing

In Python

myShoppingList = ["soap", "video games", "hand sanitizer", "eggs", "masks"]
for elem in myShoppingList:
  print(elem)

Output is the same as in JavaScript.

elem counts each element in the named list.

…a nice shorthand!

Dictionaries

But what if our data looked like this?

myShoppingList = {"soap": 0.75, "video games": 23.95, "hand sanitizer": 1.90, "eggs": 2.99, "masks": 15.50}

This isn’t a list…

It’s another data structure called a dictionary.

myDict = {"key": value, "key": value}

Similar to a database,
each item in a dictionary is a key/value pair.

We can access 1 or both of our keys/values with a For Loop:

myShoppingList = {"soap": 0.75, "video games": 23.95, "hand sanitizer": 1.90, "eggs": 2.99, "masks": 15.50}
for k, v in myShoppingList.items():
  print('key:', k, ', value:', v)

This works because on line 2
we iterate in parallel each key/value pair

Notice we iterate 2 things:
for k, v in …and not simply… for k in

Our output will be:

key: soap , value: 0.75
key: video games , value: 23.95
key: hand sanitizer , value: 1.9
key: eggs , value: 2.99
key: masks , value: 15.5

Check the fancy print() message we made on line 3;

Remember: this technique is a string concatenation!

Counting Backwards

Remember how we did this in JavaScript?

How can we accomplish this in Python?

Well, we can manipulate the arguments
in our range() function:

range([start], [stop], [step])

What do these arguments tell us?

range(5, 0, -1)

[start] at 5,

[stop] at 0,

[step] -1 each time.

What will our output be?

5
4
3
2
1

Why doesn’t it go from 4 to 0?

To get our numbers in our preferred range,
make a small adjustment to the arguments:

range(4, -1, -1)

How is this one different?

[start] at 4,

[stop] at -1,

[step] -1 each time.

Now, the output is:

4
3
2
1
0

Arithmetic Series

How can we use a For Loop
to quickly generate an increasing list of numbers?

How about a long list from 1 to 100?

In science papers you might see Capital-sigma notation:

\[\sum_{i=1}^{100-1} a_{i} = a_{i} + a_{i+1} + a_{i+2} +\dotsb+ a_{i+(100-1)}\]

which also means a list (“series”) from 1 to 100:

It means: the sum \(\sum\) of all terms \(a_{i}\)

from a low limit of 1, or \(i=1\)

to a high limit of 100, or \(i+(100-1)\)

Try this:

y = []
limit = 100
for x in range(1, limit + 1):
    y.append(x)
print(y)

For this, we [1] make an empty list,

Then, [2] define a count variable (100),

[3] set up a For Loop from 1 to our count,

[4] collect all indices x into our list y,

and [5] print the final list.

range(1, limit + 1)

Our arguments ensure the output is correct:

[start] at 1,

and [stop] at limit + 1.

We add 1 to limit because the loop will terminate at 101,
after 100 has been appended to the list!

That’s how we get numbers from 1 to 100…

The output is correct!

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]

We’ve collected all numbers into 1 giant list.

Sometimes, collecting an increasing number
of elements is called accumulation.

Finé

Now, time to do the labs…