View
217
Download
1
Category
Preview:
Citation preview
1
Loop and Set operations
2
Creating a loop
Loops are used to repeat a computation.
Let’s see the example of factorial computation.
Let’s compute 10! = 10*9*8*…*1
3
Creating a loop
1) Make a list of evaluation step by step
10
10*9
(10*9)*8
((10*9)*8)*7
…
4
Creating a loop
2) Assign intermediate results into variables
f10 = 10
f9 = 10*9
f8 = (10*9)*8
f7 = ((10*9)*8)*7
…
f1 = ((10*9)*8)*7* … *1
5
Creating a loop
3) Replace an expression with an equivalent variable.
f10 = 10
f9 = f10*9
f8 = f9*8
f7 = f8*7
…
f1 = f2*1
f10 = 10
f9 = 10*9
f8 = (10*9)*8
f7 = ((10*9)*8)*7
…
f1 = ((10*9)*8)*7* … *1
6
Creating a loop
4) Check if variables can be reduced into a single
variable.
f10 = 10
f10 = f10*9
f10 = f10*8
f10 = f10*7
…
f10 = f10*1
f = 10f = f*9f = f*8f = f*7…f = f*1
If possible, use a meaningful variable name
7
Creating a loop
5) Identify numbers or values which changes.
factorial = 10
factorial = factorial*9
factorial = factorial*8
factorial = factorial*7
…
factorial = factorial*1
8
Creating a loop
6) Find a general formula or sequence to generate those
values.
factorial = 10
factorial = factorial*9
factorial = factorial*8
factorial = factorial*7
…
factorial = factorial*1
9
Creating a loop
7) In this example, the changing sequence is [10,9,8,…,1]
factorial = 10
factorial = factorial*9
factorial = factorial*8
factorial = factorial*7
…
factorial = factorial*1
10
Creating a loop
8) Replace values with a variable; L = [10,9,8,…,1]
factorial = L[0]
factorial = factorial*L[1]
factorial = factorial*L[2]
factorial = factorial*L[3]
…
factorial = factorial*L[9]
11
Creating a loop
9) Initialize the output variable and make the recurring formula as
general as possible
factorial = 1
factorial = factorial*L[0]
factorial = factorial*L[1]
factorial = factorial*L[2]
factorial = factorial*L[3]
…
factorial = factorial*L[9]
12
Creating a loop
10) Introduce for or while statement to make a loop
for recurrences
L = [10,9, … ,1]
factorial = 1
for e in L:
factorial = factorial * e
13
Understanding a loop
L = [10,9, … ,1]
factorial = 1
for e in L:
factorial = factorial * e
Identify counter variables
14
Understanding a loop
L = [10,9, … ,1]
factorial = 1
for e in L:
factorial = factorial * e
Here, the counter variable is e; [10, 9, … , 1]
15
Understanding a loop
L = [10,9, … ,1]
factorial = 1
for e in L:
factorial = factorial * e
Expand the repeated block with examples of
counter variables
16
Understanding a loop
L = [10,9, … ,1]
factorial = 1
factorial = factorial * 10
factorial = factorial * 9
factorial = factorial * 8
…
Expand the repeated block with examples of counter
variables
17
Understanding a loop
L = [10,9, … ,1]
factorial = 1
factorial = factorial * 10
factorial = factorial * 9
factorial = factorial * 8
…
Replace the overwritten variable with actual expressions
18
Understanding a loop
L = [10,9, … ,1]
factorial = 1
factorial = 1 * 10
factorial = (1 * 10) * 9
factorial = ((1 * 10) * 9) * 8
…
Find out the last expression!
19
Understanding a loop
L = [10,9, … ,1]
factorial = 1
factorial = 1 * 10
…
factorial = 1*10*9*8*7* … *2*1 = 10!
If possible, think an equivalent mathematical
expression
20
Example: conditional counting
Count 2 from [2,3,1,0,2,1,0,4,2]
Devise a function which works with one or two
arguments.
Sometimes, it is not obvious at first.
Then, start from the end
some_func(<intermediate_result>, 2) = 3; (for this
case)
Guess the signature of some_func:
some_func(<?>,<number>) = <number>
21
Example: conditional counting
The signature is …
some_func(<?>,<number>) = <number>
Guess/Imagine what will happen with specific examples
some_func(<?>,2) = <?> + 1; why?
some_func(<?>,1) = <?>; why?
Find out the missing type <?>; <number>
22
Example: conditional counting
Now, the signature is complete
some_func(<number>,<number>) = <number>
Let’s try to draw specific exemplar cases:
some_func(<number>,2) = <number> + 1
some_func(<number>,1) = <number>
Introduce a variable, namely, count, to replace the type
23
Example: conditional counting Concrete exemplar cases are:
some_func(count,2) = count + 1
some_func(count,1) = count
Wire exemplar cases with if statement
some_func(count, n) =
count + 1 # if n equals to 2count # if n is not 2
24
Example: conditional counting
Define a function based on the previous analysis
def count_2(count, n):
if n == 2:
return count + 1
return count
25
Example: conditional counting
Test if it can be applied with an example list as we did at
the beginning of this class.
L = [1,2,0]
count_2(0,1) = 0 ; note the initial counter 0
count_2(0,2) = 1 ; this zero is different from the above
count_2(1,0) = 1 ;
count_2(count_2(count_2(0,1),2),0)
26
Example: conditional counting
L = [1,2,0]
count_2(0,1) = 0 # note the initial counter 0
count_2(0,2) = 1 # this zero is different from the above
count_2(1,0) = 1 #
Identify changing variable; 1, 2, 0
Identify accumulated values (or production values): 0,1,1
27
Example: conditional counting
L = [1,2,0]
count = count_2(0,L[0]) = 0
count = count_2(0,L[1]) = 1
count = count_2(1,L[2]) = 1
Replace changing values with a loop variable.
Replace the accumulating value with a variable.
28
Example: conditional counting
L = [1,2,0]
count = 0
for e in L:
count = count_2(count, e)
Introduce a for or while statement.
However, sometimes, the function is not necessary.
Try to expand the function within the loop
29
Example: conditional counting
Do you remember?
def count_2(count, n):
if n == 2:
return count + 1
return count
30
Example: conditional counting
L = [1,2,0]
count = 0
for e in L:
if e == 2:
count = count + 1
Maybe this is more comprehensive than before.
Loops and function calls are essentially identical.
Loops are successive function calls!
31
Example: conditional counting
How to generalize this example?
What is the base operation?
‘x == 2’
Replace the base operation with a function
def test_2(x):
return x==2
32
Example: conditional counting
Make a big function; count_if(L, func)
The signature of the function is …
count_if(<list>,<function>) <number>
Counting 2 is calling count_if(L, test_2)
def test_2(x):
return x==2
33
Example: conditional counting
The complete version of count_if(L,cond)
def count_if(L, cond):
count = 0
for e in L:
if cond(e):
count = count + 1
return count
count_if(L, test_2) # will count 2s in L
34
Example: conditional counting
See some demo!
35
Example: conditional collection
The variation of count_if(L,cond)
def collect_if(L, cond):
collection = []
for e in L:
if cond(e):
collection = collection + [e]
return collection
36
Lambda Function
Anonymous function
lambda x: x + 2
Equivalent to
def plus2(x):
return x+2
Just a short form of a function without name and return
37
Example: conditional collection
Collecting 2 or 3’s multiples:
collect_if(range(1,100), \
lambda x: x%2==0 or x%3==0)
Intersection of two lists L1 and L2:
collect_if(L1, \
lambda x: x in L2)
38
Example: conditional collection
Sometimes, we need [ f(x0), f(x1), …, f(xn) ] from
[x0,x1,…,xn]
Let’s tweak collect_if(L, cond)
def collect_mapping_if(L,mapping,cond=None):
out = []
for e in L:
if cond and cond(e):
out.append(mapping(e))
return out
39
Example: conditional collection
See some demo
40
List Comprehension
List comprehension is nothing but a collect_mapping_if.
[ x for x in L ] is equivalent to
collect_mapping_if(L,lambda x: x,None)
[ x*x for x in L ] is equivalent to
collect_mapping_if(L,lambda x:x*x)
[ x for x in range(0,10) if x==2 ] is equivalent to
collect_mapping_if(L,lambda x:x, lambda x:x==2)
41
List Comprehension
See some demo
List comprehensions could be nested
42
Can you?
Can you reduce an expression into a variable?
Can you expand a variable or a function into an
embedded form?
Then, you are free!
43
Revisiting Set operations
What’s the definition of the intersection?
As seen before, (but watch out for duplicates!)
collect_if(L1, lambda x: x in L2)
for e in L1:
if e in L2:
o.append(e)
44
Revisiting Set operations
What’s the definition of the subtraction?
As seen before,
subtract(L1,L2)
collect_if(L1, lambda x: x not in L2)
for e in L1:
if (e not in L1) :
o.append(e)
45
Revisiting Set operations
What’s the definition of the union?
The union is somewhat different because of
duplicates.
union(L1,L2) = L1 + subtract(L2,L1)
or union(L1,L2) = L1+L2 – intersect(L1,L2)
46
Revisiting Set operations
Using the list comprehension,
intersection(L1,L2)
collect_if(L1, lambda x: x in L2)
[ e for e in L1 if x in L2 ]
subtract(L1,L2)
collect_if(L1, lambda x: x not in L2)
[ e for e in L1 if x not in L2 ]
47
Revisiting the unique operation
Finding the unique elements in a list L.
Let’s define a function to determine an element’s
uniqueness.
For example, L = [ 1, 2, 1 ]; unique(L) [1, 2]
is_unique(<interim>, 1) [ 1 ]
is_unique(<interim>, 2) [ 1, 2 ]
is_unique(<interim>, 1) [ 1, 2 ]
48
Revisiting the unique operation
is_unique(<interim>, 1) [ 1 ]
is_unique(<interim>, 2) [ 1, 2 ]
is_unique(<interim>, 1) [ 1, 2 ]
Replace <interim> with previous results;
is_unique(<interim>, 1) [1]
is_unique([1], 2) [1, 2]
is_unique([1,2], 2) [1, 2]
There is a pattern. Can you wire the above with if-statement?
49
Revisiting the unique operationis_unique(<interim>, 1) [1] # don’t know
is_unique([1], 2) [1, 2] # 2 was added because 2 is not in [1]
is_unique([1, 2], 2) [1, 2] # 2 was not added because 2 is in [1,2]
It’s somewhat complicated though
is_unique(<interim>, 1) [1]
is_unique(<interim>, 2) add 2 if <interim> has no 2
is_unique(<interim>, 2) don’t add 2 if <interim> has 2
Do you see what I am seeing?
50
Revisiting the unique operationis_unique(<interim>, 1) [1]
is_unique(<interim>, 2) add 2 if <interim> has no 2
is_unique(<interim>, 2) don’t add 2 if <interim> has 2
We can code the above analysis as …
def is_unique(L, e):
if e not in L:
return L + [e] # or L.append(e)
Let’s expand with some examples:
is_unique(is_unique(is_unique(?,1),2),2)
51
Revisiting the unique operationis_unique(is_unique(is_unique(?,1),2),2)[1,2]
I believe that you can make a loop from the above
uniques = []for e in L:
uniques = is_unique(uniques, e)
Let’s expand with the is_unique function
uniques = []for e in L:
if e not in uniques:uniques.append(e)
52
Loops and Set operations
Are these make sense to
you?
53
One more thing!
List indexing
An element of a list or a part of a list can be easily
accessed by indexing [] operator.
For example
L = [1,2,3]
print L[0], L[1], L[-1], L[-3] # will print 1, 2, 3, 1
print L[0:2], L[1:], L[:2], L[0:3:2], L[::-1]
>>> [1,2], [2,3], [1,2], [1,3], [3,2,1]
54
Be prepared!
Indexing is an evil…
Sometimes there is no way
to escape or avoid,
unfortunately…
55
Next week,
We will learn about sorting,
searching, and files
Recommended