Section #7 Solutions


Written by Juliette Woodrow, Brahm Capoor, Anna Mistele, and John Dalloul


Using map

                    
temps_F = [45.7, 55.3, 62.1, 75.4, 32.0, 0.0, 100.0]

#convert from Fahrenheit to Celsius
temps_C = list(map(lambda f : (f - 32) * 5 / 9, temps_F))
print('C: ', temps_C)
                    
                
original_headings = [(30, 'N'), (359, 'N'), (340, 'N'), (270, 'W'), (124, 'E'), (149, 'S'), (219, 'S')]

def update_heading(reading):
  updated_heading = (reading[0] + 22) % 360
  updated_direction = calc_direction(updated_heading)
  return (updated_heading, updated_direction)

def calc_direction(heading):
  if 46 <= heading and heading <= 135:
    return 'E'
  elif 136 <= heading and heading <= 225:
    return 'S'
  elif 225 <= heading and heading <= 315:
    return 'W'
  else:
    return 'N'

update_list = list(map(update_heading, original_headings))
print(update_list)
map(lambda word: word[::-1], text.split())
# OR
def reverse(s):
  result = ""
  for ch in s:
    result = ch + result 
  return result 

map(reverse, text.split())
                    
                
                    
def linear_transformation(vector, scale, shift):
    """
    Takes in a vector (list of numbers), a scale factor, and a shift constant and returns the vector
    where the ith term is equivalent to the ith term of the original vector multiplied by the scale
    and added to the shift.
    """
    # can set the lambda function to a variable to make code more readable
    linear_transformation_fn = lambda x : scale * x + shift 
    
    result = list(map(linear_transformation_fn, vector))
    return result
                    
                
                
def convert_times(times):
    conversion_factor = 1.25 * 1760 / 100  # divide total yards in 1.25 miles by 100 yards
    return list(map(lambda x : x / conversion_factor, times))
                    
                

Reading map

                
counting = [5, 6, 7, 8]
jenny = [8, 6, 7, 5, 3, 0]
map(lambda lst: lst.append(9), [counting, jenny])
# => 
"""
Whoa! Why does this iterable not contain anything? `map` replaces each
element with the *return* value of the function call. In this case, the
append function returns None, but modifies the value of the list... Tricky!
"""

counting = [5, 6, 7, 8]
jenny = [8, 6, 7, 5, 3, 0]
map(lambda lst: lst + [9], [counting, jenny])
# => <[5, 6, 7, 8, 9], [8, 6, 7, 5, 3, 0, 9]>
"""
This works as expected, because lst1 + lst2 *returns* a new list. In our
case, that's the original list, with the number 9 appended.
"""
          
                
            

Sorting with lambdas

                
>>> strs = ['apple', 'BANANA', 'candy', 'aardvark']
# 1.
>>> sorted(strs, key=lambda word : word.lower())
['aardvark', 'apple', 'BANANA', 'candy']
# 2.
>>> sorted(strs, key=lambda word : word.lower()[len(word)-1])
['BANANA', 'apple', 'aardvark', 'candy']

# 3.
>>> nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> sorted(nums, key=lambda num:abs(num-3.14))
[3, 4, 2, 5, 1, 6, 7, 8, 9, 10]
>>> min(nums, key=lambda num:abs(num-3.14))
3
>>> max(nums, key=lambda num:abs(num-3.14))
10

# 4A.
>>> sorted(rentals, key=lambda room_tuple:room_tuple[1])
[('elm st.', 1, 1200), ('pine st.', 2, 1600), ('main st.', 4, 4000)]
# 4B.
>>> sorted(rentals, key=lambda room_tuple:room_tuple[2])
[('elm st.', 1, 1200), ('pine st.', 2, 1600), ('main st.', 4, 4000)]
# 4C.
>>> sorted(rentals, key=lambda room_tuple:room_tuple[2]/room_tuple[1])
[('pine st.', 2, 1600), ('main st.', 4, 4000), ('elm st.', 1, 1200)]
>>> min(rentals, key=lambda room_tuple:room_tuple[2]/room_tuple[1])
('pine st.', 2, 1600)
                
            

Tweets Revisited

Part 1

                    
def reverse_keys(flat_counts):
    for pair in sorted(flat_counts.items(), reverse=True):
        key = pair[0]
        print(key)
                    
                
                
def most_used(flat_counts):
    """
    Given a non-empty "flat" counts dict of tags, return the tag
    that has the largest count.
    """
    sorted_tags = sorted(flat_counts.items(), key=lambda x: x[1], reverse=True)
    print(sorted_tags[:10])
                
            

One Liners

  • Given list of non-empty strs, write a map/lambda and/or list comprehension to form a list of the strings in upper case.

                        
    >>> strs = ['Rhyme', 'Donut', '3xx', 'Orange']
    # Map
    >>> list(map(lambda s: s.upper(), strs))
    # List comprehension                
    >>> [s.upper() for s in strs]
    
  • Given list of (x, y) points, write a sorted/lambda expression to order these points in decreasing order by the sum of the x+y of each point.

                        
    >>> points = [(10, 0), (1, 3), (3, 2), (5, 4)]
    >>> sorted(points, key=lambda pt: pt[0] + pt[1], reverse=True)
    
# a. Given a list of numbers.
# Call map() to produce a result where each
# number is multiplied by -1. (or equivalently write a comprehension)
>>> nums = [3, 0, -2, 5]
# yields [-3, 0, 2, -5]
# your expression:

map(lambda x: x*(-1), nums)


or 

[num*(-1) for num in nums]


# b. Given a list of (x, y) "point" tuples where x and y are int values.
# Call map() to produce a result where each (x, y) is replaced
# by the sum of x and y. (or equivalently write a comprehension)
>>> points = [(1, 2), (4, 4), (1, 3)]
# yields [3, 8, 4]
# your expression:

map(lambda pt: pt[0]+pt[1], points)

or 

[pt[0]+pt[1] for pt in points]



# c. Given a list of (city-name, zip-code, current-temperature) tuples, like this
>>> cities = [('modesto', 95351, 92), ('palo alto', 94301, 80), ...]
# Call sorted() to produce a list of these tuples sorted in decreasing
# order by temperature.
# your expression:

sorted(cities, key=lambda city: city[2], reverse=True)



# d. Given a non-empty list of (flower-name, scent-score, color-score) tuples
# like the following, scores are in the range 1 .. 10
>>> flowers = [('rose', 4, 8), ('orchid', 7, 2), ... ]
# Call max() or min() to return the flower tuple with the highest scent score.
# your expression:

max(flowers, key=lambda flower: flower[1])
 

Capstone CS106A Problems


Dict File problem from Winter Quarter Quiz #3

  def read_posts(filename):
    posts = {}
    with open(filename) as f:
        for line in f:
        # could do .strip(), not marking off
        words = line.split('^')
        celeb = words[0]
        for chan in words[1:]:
            if chan not in posts:
                posts[chan] = []
            inner = posts[chan]
            if celeb not in inner:
                inner.append(celeb)

        return posts
  

Prime Files

                
def prime_file(filename):
    """
    The given file contains text data on each line as follows.
    Each line is made of a mixture of non-empty alphabetic words
    and non-negative ints, all separated by colons. The numbers can be distinguished
    since their first char is a digit. Lines like this:
    aaa:123:420:xyz:xxx:44:zz:a
    The first element is the "prime" for that line, and is always alphabetic.
    Read through all the lines and build a dict with a key for each prime,
    and its value is a list of all the int number values from all the lines
    with that prime.
    Add every number to the list, even if it is a duplicate.
    When all the data is loaded, print the primes in alphabetical order
    1 per line, each followed by its sorted list of numbers, like this
    aaa [44, 123, 123, 125, 420, 693]
    bbb [16, 23, 101, 101]
    """
    primes = {}
    with open(filename) as f:
        for line in f:
            parts = line.split(':')
            prime = parts[0]
            # pick out which parts are ints - comprehension is cute here
            # or could do this as a regular old for-loop with an append
            # inside is fine and full credit.
            nums = [int(part) for part in parts if part[0].isdigit()]
            if not prime in primes:
                primes[prime] = []
            primes[prime].extend(nums)
    # now output
    for prime in sorted(primes.keys()):
        print(prime, sorted(primes[prime]))
                
            

Dict File

                
def count_zips(filename):
    states = {}
    with open(filename) as f:
        for line in f:
            pass
            words = line.split(',')
            state = words[0]
            if state not in states:   
                states[state] = {}
            counts = states[state]    
            for word in words[1:]:    
                zip = word[:5]        
                if zip not in counts:
                    counts[zip] = 0
                counts[zip] += 1

    for state in sorted(states.keys()):
        print(state)
        counts = states[state]
        for zip in sorted(counts.keys()):
            print(zip, counts[zip])
                
            

Lightning

                
def parse_lightning(filename):
    states = {}
    with open(filename) as f:
        for line in f:
            pass
            words = line.split(',')
            i_state = len(words) - 1
            state = words[i_state].strip() # not grading off: remove \n
            if state not in states:
                states[state] = []
            nums = states[state]            # decomp by var
            for numstr in words[:i_state]:  # omit last elem
                nums.append(int(numstr))
               
    for state in sorted(states.keys()):
        print(state, states[state], sum(states[state]))
                
            

© Stanford 2020 | CS106A has been developed over decades by many talented teachers. Website designed by Chris Piech.