Understanding the map function
map
isn't particularly pythonic. I would recommend using list comprehensions instead:
map(f, iterable)
is basically equivalent to:
[f(x) for x in iterable]
map
on its own can't do a Cartesian product, because the length of its output list is always the same as its input list. You can trivially do a Cartesian product with a list comprehension though:
[(a, b) for a in iterable_a for b in iterable_b]
The syntax is a little confusing -- that's basically equivalent to:
result = []for a in iterable_a: for b in iterable_b: result.append((a, b))
map
doesn't relate to a Cartesian product at all, although I imagine someone well versed in functional programming could come up with some impossible to understand way of generating a one using map
.
map
in Python 3 is equivalent to this:
def map(func, iterable): for i in iterable: yield func(i)
and the only difference in Python 2 is that it will build up a full list of results to return all at once instead of yield
ing.
Although Python convention usually prefers list comprehensions (or generator expressions) to achieve the same result as a call to map
, particularly if you're using a lambda expression as the first argument:
[func(i) for i in iterable]
As an example of what you asked for in the comments on the question - "turn a string into an array", by 'array' you probably want either a tuple or a list (both of them behave a little like arrays from other languages) -
>>> a = "hello, world" >>> list(a)['h', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd']>>> tuple(a)('h', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd')
A use of map
here would be if you start with a list of strings instead of a single string - map
can listify all of them individually:
>>> a = ["foo", "bar", "baz"]>>> list(map(list, a))[['f', 'o', 'o'], ['b', 'a', 'r'], ['b', 'a', 'z']]
Note that map(list, a)
is equivalent in Python 2, but in Python 3 you need the list
call if you want to do anything other than feed it into a for
loop (or a processing function such as sum
that only needs an iterable, and not a sequence). But also note again that a list comprehension is usually preferred:
>>> [list(b) for b in a][['f', 'o', 'o'], ['b', 'a', 'r'], ['b', 'a', 'z']]
map
creates a new list by applying a function to every element of the source:
xs = [1, 2, 3]# all of those are equivalent — the output is [2, 4, 6]# 1. mapys = map(lambda x: x * 2, xs)# 2. list comprehensionys = [x * 2 for x in xs]# 3. explicit loopys = []for x in xs: ys.append(x * 2)
n-ary map
is equivalent to zipping input iterables together and then applying the transformation function on every element of that intermediate zipped list. It's not a Cartesian product:
xs = [1, 2, 3]ys = [2, 4, 6]def f(x, y): return (x * 2, y // 2)# output: [(2, 1), (4, 2), (6, 3)]# 1. mapzs = map(f, xs, ys)# 2. list compzs = [f(x, y) for x, y in zip(xs, ys)]# 3. explicit loopzs = []for x, y in zip(xs, ys): zs.append(f(x, y))
I've used zip
here, but map
behaviour actually differs slightly when iterables aren't the same size — as noted in its documentation, it extends iterables to contain None
.