The Map Method

The map() method is a way to apply the effect of a function on every element in an iterable. It iterates over the iterable, and passes each element in turn into the function you provide it. Each of these return values are appended to a (new) list, which map() returns.

Exercise 7.1: Make a custom map

Instructions

  • Build a function called my_map that takes a function and an interable as arguments.
  • For this example, make the function it that map takes as an argument a function that takes something as an input, does something to it, and returns the changed element. Examples:
    • It takes a number and returns the number squared
    • It takes a string and returns the string reversed
    • …etc.
  • Your my_map function should iterate over your iterable, and pass each element into the function you gave it
  • It should compile the return values of that step into a new list, which it returns

Exercise 7.2

  • Make a list of numbers: NUMBERS = range(1, 100)
  • Run this numbers through your my_map function with an anonymous function which doubles each number
  • Print the output

Did all of this work?

Here’s my solution


Exercise 8

  • Take this list of strings:
PICTURES = ["picture1", "georgi_paws_everywhere", "custom_wreath"]
  • Use your custom my_map to map the extension .jpg on to the end of each of these strings

  • Did you get it working? Here’s my solution


Exercise 9

  • Make a new list of numbers: numbers = range(4)
  • Take this list of strings:
NAMES = ['Rebecca', 'Georgi', 'Reed', 'Thom Yorke']
  • Use your my_map method to return a list of tuples, the first element of the tuple should be the number in numbers
  • The second element in the tuple should be the name in names at the index of each number from numbers
  • Does that make sense? An example tuple would be:
    • (0, 'Rebecca')

Hints:

  • If using a lambda function confuses you, make a separate function
  • Tuples are immutable, so you’ll need to construct the tuple in that function (you can’t append() elements onto a tuple)

  • Did you get it working? Here’s my solution

The Built-In Map Function


map(function, iterable, …)

From the documentation:

Apply function to every item of iterable and return a list of the results. If additional iterable arguments are passed, function must take that many arguments and is applied to the items from all iterables in parallel. If one iterable is shorter than another it is assumed to be extended with None items. If function is None, the identity function is assumed; if there are multiple arguments, map() returns a list consisting of tuples containing the corresponding items from all iterables (a kind of transpose operation). The iterable arguments may be a sequence or any iterable object; the result is always a list.

To figure out what this does I played around with it, starting with this part:

If function is None, the identity function is assumed; if there are multiple arguments, map() returns a list consisting of tuples containing the corresponding items from all iterables (a kind of transpose operation). The iterable arguments may be a sequence or any iterable object; the result is always a list.

By passing in None as the function value, it says “the identity function is assumed”. I don’t know what that means, but I tried giving it None as the function, and giving it both NUMBERS and NAMES in the iterable list, and look what it did:

>>> NUMBERS = range(4)
>>> NAMES = ['Rebecca', 'Georgi', 'Reed', 'Thom Yorke']
>>>
>>> results = map(None, NUMBERS, NAMES)  # None as the function, and added both iterables
>>> print results
[(0, 'Rebecca'), (1, 'Georgi'), (2, 'Reed'), (3, 'Thom Yorke')]
>>> 

Well, that’s cool. Our custom map function certainly won’t do that. That takes care of Exercise 9. This seems like a really easy way to combine lists.

Now what about that first sentence:

If additional iterable arguments are passed, function must take that many arguments and is applied to the items from all iterables in parallel.

I tried this:

>>> NUMBERS = range(4)
>>> NAMES = ['Rebecca', 'Georgi', 'Reed', 'Thom Yorke']
>>>
>>> results = map(lambda x, y: (x, y), NUMBERS, NAMES)
>>> print results
[(0, 'Rebecca'), (1, 'Georgi'), (2, 'Reed'), (3, 'Thom Yorke')]

Then I tried this:

>>> NUMBERS = range(1, 5)  # I changed this to be the numbers 1 through 4
>>> NAMES = ['Rebecca', 'Georgi', 'Reed', 'Thom Yorke']
>>> results = map(lambda x, y: x*y, NUMBERS, NAMES)  # I changed this to multiply the values
>>> print results
['Rebecca', 'GeorgiGeorgi', 'ReedReedReed', 'Thom YorkeThom YorkeThom YorkeThom Yorke']

This means that map() takes the first elements from both iterables, and feeds them into the function.

1 * 'Rebecca' = 'Rebecca'

Then it takes the second element from both iterables and feeds them into the function:

2 * 'Georgi' = 'GeorgiGeorgi'

Then:

3 * 'Reed' = 'ReedReedReed'

And then lots of Thom Yorke.


Before writing this I didn’t know that map() could take None as an argument for the function, or that it could take multiple iterables and work through them in parallel.

Thank you for reading this and learning with me!




Written on May 3, 2016