EECS 110: Lec 5: List Comprehensions Aleksandar Kuzmanovic Northwestern University
-
Upload
ralf-nichols -
Category
Documents
-
view
218 -
download
1
Transcript of EECS 110: Lec 5: List Comprehensions Aleksandar Kuzmanovic Northwestern University
EECS 110: Lec 5: List Comprehensions
Aleksandar Kuzmanovic
Northwestern University
http://networks.cs.northwestern.edu/EECS110-s15/
The building blocks of functiona
l computing
data, sequencesconditionalsrecursion
EECS 110 today
List Comprehensions
map and applications
Homework 1 - submitted
Homework 2 - this coming Sunday…!3 problems
1 lab problem Tuesday
2 python problems
"Quiz" on recursion
def power(b,p):
Names:
Handle negative values of p, as well.
""" returns b to the p power using recursion, not ** inputs: ints b and p output: a float"""
Want more power?
power(5,2) == 25.0
For example, power(5,-1) == 0.2 (or so)
def sajak(s):
sajak('wheel of fortune') == 6
""" returns the number of vowels in the input string, s"""
def power(b,p): """ inputs: base b and power p (an int)
implements: b**p = b*b**(p-1)
"""
if p == 0:
return
if p > 0:
return
else:
# p < 0
return
def power(b,p): """ inputs: base b and power p (an int)
implements: b**p = b*b**(p-1)
"""
if p == 0:
return 1
if p > 0:
return
else:
# p < 0
return
def power(b,p): """ inputs: base b and power p (an int)
implements: b**p = b*b**(p-1)
"""
if p == 0:
return 1
if p > 0:
return b*power(b,p-1)
else:
# p < 0
return
def power(b,p): """ inputs: base b and power p (an int)
implements: b**p = b*b**(p-1)
"""
if p == 0:
return 1
if p > 0:
return b*power(b,p-1)
else:
# p < 0
return 1/power(b,-1*p)
def sajak(s):
Base case?
when there are no letters, there are ZERO vowels
if it is NOT a vowel, the answer is
Rec. step?
Look at the initial character.
if it IS a vowel, the answer is
def sajak(s):
Base case?
when there are no letters, there are ZERO vowels
if it is NOT a vowel, the answer is just the number of vowels in the rest of sRec.
step?
Look at the initial character.
if it IS a vowel, the answer is 1 + the number of vowels in the rest of s
def sajak(s):
if len(s) == 0:
return 0
else:
Checking for a vowel: Try #1
and
or
not
same as in English!
but each side has to be a complete boolean value!
Base Case
def sajak(s):
if len(s) == 0:
return 0
else:
Checking for a vowel: Try #1
and
or
not
same as in English!
but each side has to be a complete boolean value!
if s[0] == 'a' or s[0] == 'e' or…
Base Case
def sajak(s):
if len(s) == 0:
return 0
else:
if s[0] not in 'aeiou':
return sajak(s[1:])
else:
return 1+sajak(s[1:])
if it is NOT a vowel, the answer is just the number of vowels in the rest of s
if it IS a vowel, the answer is 1 + the number of vowels in the rest of s
Base Case
Rec. Step
functional programming
>>> 'fun' in 'functional'True
Key ideas in functional programming
• create small building blocks (functions)
• leverage self-similarity (recursion)
• representation via list structures (data)
Compose these together to solve or investigate problems.
elegant and concisenot maximally efficient for
the computer…vs.
return to recursion
Composing functions into specific applications
Creating general functions that will be useful everywhere (or almost…)
return to recursion
Composing functions into specific applications
Creating general functions that will be useful everywhere (or almost…)
building blocks with which to compose…
sum, range
def sum(L):
""" input: a list of numbers, L
output: L's sum
"""
if len(L) == 0:
return 0.0
else:
return L[0] + sum(L[1:])
Base Caseif the input
has no elements, its sum is zero
Recursive Case
if L does have an element, add
that element's value to the sum of the REST of the
list…
This input to the recursive call must be "smaller" somehow…
sum, range
def range(low,hi):
""" input: two ints, low and hi
output: int list from low up to hi
"""
excluding hi
sum, range
def range(low,hi):
""" input: two ints, low and hi
output: int list from low up to hi
"""
if hi <= low:
return []
else:
return
excluding hi
sum, range
def range(low,hi):
""" input: two ints, low and hi
output: int list from low up to hi
"""
if hi <= low:
return []
else:
return [low] + range(low+1,hi)
excluding hi
Recursion: Good News/Bad News
Recursion is common (fundamental) in functional programming
def dblList(L):
""" Doubles all the values in a list.
input: L, a list of numbers """
if L == []:
return L
else:
return [L[0]*2] + dblList(L[1:])
But you can sometimes hide it away!
Map: The recursion "alternative"
def dbl(x):
return 2*x
def sq(x):
return x**2
def isana(x):
return x=='a’
>>> map( dbl, [0,1,2,3,4,5] )[0, 2, 4, 6, 8, 10]
>>> map( sq, range(6) )[0, 1, 4, 9, 16, 25]
>>> map( isana, 'go away!' )[0, 0, 0, 1, 0, 1, 0, 0]
Hey… this looks a bit False to
me!
(1) map always returns a list
(2) map(f,L) calls f on each item in L
Map !
def dblList(L): """ Doubles all the values in a list. input: L, a list of numbers """ if L == []: return L else: return [L[0]*2] + dblList(L[1:])
Without map
def dbl(x): return x*2
def dblList(L): """ Doubles all the values in a list. input: L, a list of numbers """ return map(dbl, L)
With map!
Map: a higher-order function
In Python, functions can take other functions as input…
def map( f, L ):
KeyConcept
Functions ARE data!
Why use map?
Faster execution in Python – map optimized for operations in lists
More elegant / shorter code, “functional in style”
Avoid rewriting list recursion (build once, use lots)
Mapping without map: List Comprehensions
>>> [ dbl(x) for x in [0,1,2,3,4,5] ][0, 2, 4, 6, 8, 10]
>>> [ x**2 for x in range(6) ][0, 1, 4, 9, 16, 25]
>>> [ c == 'a' for c in 'go away!' ][0, 0, 0, 1, 0, 1, 0, 0]
Anything you want to happen to
each element of a list
output
output
output
input
input
input
name that takes on the value of each element in
turn the list (or string)
any name is OK!
Mapping without map: List Comprehensions
>>> [ dbl(x) for x in [0,1,2,3,4,5] ][0, 2, 4, 6, 8, 10]
>>> [ x**2 for x in range(6) ][0, 1, 4, 9, 16, 25]
>>> [ c == 'a' for c in 'go away!' ][0, 0, 0, 1, 0, 1, 0, 0]
def dbl(x):
return 2*x
def sq(x):
return x**2
def isana(x):
return x=='a’
>>> map( dbl, [0,1,2,3,4,5] )[0, 2, 4, 6, 8, 10]
>>> map( sq, range(6) )[0, 1, 4, 9, 16, 25]
>>> map( isana, 'go away!' )[0, 0, 0, 1, 0, 1, 0, 0]
List Comprehensions
def len(L): if L == []: return 0 else: return 1 + len(L[1:])
len(L)
implemented via raw recursion
sScore(s)
sajak(s)
def sajak(s): if len(s) == 0: return 0 else: if s[0] not in 'aeiou': return sajak(s[1:]) else: return 1+sajak(s[1:])
def sScore(s): if len(s) == 0: return 0 else: return letScore(s[0]) + \
sScore(s[1:])
scrabble score
List Comprehensions
LC = [1 for x in L] return sum( LC )
len(L)
sajak(s)LC = [c in 'aeiou' for c in s]return sum( LC )
# of vowels
List Comprehensions
LC = [1 for x in L] return sum( LC )
len(L)
sScore(s)
sajak(s)LC = [c in 'aeiou' for c in s]return sum( LC )
scrabble score
# of vowels
LC = [ letScore(c) for c in s] return sum( LC )
Quiz Write each of these functions concisely using list comprehensions…
Write def count(e,L):
Write def lotto(Y,W):
input: e, any element L, any list or stringoutput: the # of times L contains e example: count('f', 'fluff') == 3
input: Y and W, two lists of lottery numbers (ints)output: the # of matches between Y & W example: lotto([5,7,42,44],[3,5,7,44]) == 3
Y are your numbers
W are the winning numbers
Name(s):
Remember True == 1 and False == 0
Extra! Write def divs(N):
input: N, an int >= 2output: the number of positive divisors of Nexample: divs(12) == 6 (1,2,3,4,6,12)
Quiz
LC = [x==e for x in L] return sum( LC )
count(e,L)
divs(N)
lotto(Y,W)LC = [c in Y for c in W]return sum( LC )
LC = [ N%c==0 for c in range(1,N+1)] return sum( LC )