Before the Lab
Background
Discussion
- Time
- 10 minutes
- Activity
- Discussion
Globbing and List comprehensions
- Time
- 20 minutes
- Activity
- individual
List Comprehensions can be seen as a special kinds of for loops. Construct an equivalent list comprehension to the given for loop.
#!/usr/bin/python3
import glob
import os
new_dir = os.path.expanduser("~/fcshome/cs2613/labs/test")
python_files_for = []
for file in glob.glob("*.py"):
python_files_for.append(os.path.join(new_dir,file))
python_files_comp = ____________________________________________________________
Here is a test to make sure your two constructions are really
equivalent; the use of sorted
is probably unneeded here, but we
don't need to depend on the order returned by glob
being consistent.
Put the following in ~fcshome/cs2613/labs/L15/test_globex.py
.
#!/usr/bin/python3
import globex
def test_for():
assert sorted(globex.python_files_for) == sorted(globex.python_files_comp)
In fact list comprehensions are really closer to a convenient syntax
for map
, which you may remember from Racket and JavaScript. Python
also has map
and lambda
, although these are considered less
idiomatic than using list comprehensions. Fill in the body of the
lambda
(should be similar or identical to your list comprehension
expression).
python_files_map = map(lambda file: __________________________, glob.glob("*.py"))
The following test should pass
def test_map():
assert sorted(globex.python_files_comp) == sorted(globex.python_files_map)
Dictionary Comprehensions
- Time
- 20 minutes
- Activity
- Individual
Dictionary Comprehensions are quite similar to list comprehensions, except that they use
{ key: val for ...}
Create a file ~/fcshome/cs2613/labs/L15/list2dict.py
with a function
list2dict
that transforms a list into a dictionary indexed by
integers. Your function should use a dictionary comprehension and
pass the following tests. One approach uses the python builtin
range. It
may help to write it first using a for
loop.
#!/usr/bin/python3
from list2dict import list2dict
def test_empty():
assert list2dict([]) == {}
def test_abc():
dictionary=list2dict(["a", "b", "c"])
assert dictionary == {1: 'a', 2: 'b', 3: 'c'}
Filtered List Comprehensions
- Time
- 25 minutes
- Activity
- individual
Looking at the discussion of
list comprehensions,
we can see that it is possible to filter the list of values used in
the the list comprehension with an if
clause. Use this syntax to
re-implement the function drop-divisible
from A1.
Notice that the implementation of sieve_with
is not suitable for a
list comprehension because of the update of lst
on every iteration
(in Racket this could be done without mutation by tail recursion or
for/fold). Python does have a reduce
function (in the functools
module), but most Python programmers will prefer the 2 line loop given
here.
#!/usr/bin/python3
from math import sqrt,ceil
def drop_divisible(n,lst):
return __________________________________
def sieve_with(candidates, lst):
for c in candidates:
lst=drop_divisible(c,lst)
return lst
def sieve(n):
return sieve_with(range(2,ceil(sqrt(n))+1), range(2,n))
Your implementation should pass the following tests.
from sieve import drop_divisible
def test_drop_divisible():
assert drop_divisible(3, [2, 3, 4, 5, 6, 7, 8, 9, 10]) == [2, 3, 4, 5, 7, 8, 10]
def test_sieve():
assert sieve(10)== [2, 3, 5, 7]
Using format
- Time
- 25 minutes
- Activity
- individual
Like JavaScript, Python supports a simple way of constructing output
using the overloaded operator +
. Python also supports a more
powerful format method (similar to Racket's format function) for
combining values into a formatted output string. Use the format
method and a list comprehension to write an equivalent value into
strings_format
.
import os,glob
strings_plus = []
for p in glob.glob("*.py"):
size=os.stat(p).st_size
strings_plus.append(p + "\t" + str(size))
strings_format = __________________________________________________
Your code should pass the following test.
import formatex
def test_equality():
assert sorted(formatex.strings_plus) == sorted(formatex.strings_format)