MTEC1003 — Media Computation Skills Lab
Iteration + Collection,
Lists vs. Dictionaries
Python Methods
Arithmetic Series
and For Loops
…but in Python, NOT JavaScript!…
Simply put, iteration is the process of repeating a set of instructions until some condition is met.
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,
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!
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?
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.
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?
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)
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.
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
are written 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
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.
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
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.)
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…
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.
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.
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
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!
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!
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
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.
Now, time to do the labs…