
Mad Map: Python Road - ikalnitsky
http://kalnitsky.org/2015/06/14/mad-map/
======
crimsonalucard
[https://docs.python.org/2/howto/functional.html#built-in-
fun...](https://docs.python.org/2/howto/functional.html#built-in-functions)

The documentation here actually mentions that map() and filter () are somewhat
obsolete in python.

------
ekimekim
To perhaps shed a little light on the None thing and why it would be useful,
consider the following:

    
    
        def munge(data, convert=None):
            data = map(convert, data)
            ...
    

ie. treating None as identity gives you sane default behaviour in the case
that you want to optionally provide a mapping functionality. Granted, you can
easily do an "if convert is not None" but I think this is slightly nicer.

Welp, add it to the list of things I think are better in py2 than py3.

~~~
christianmann
Or you could do

    
    
       def munge(data, convert=lambda x: x)

~~~
ah-
This is C++ style thinking, but that way it has to copy the array and run that
function on every element. If it supports none it can just return the original
data.

------
svisser
map() isn't all that useful in Python.

If you want a list it's more straightforward to write:

    
    
        [f(x) for x in my_iterable]
    

If you don't want a list it's more straightforward to write:

    
    
        for x in my_iterable:
            y = f(x)

~~~
ekimekim
I tend to use map if my mapping function is already available to me as a
callable. If I would use a lambda, I tend to use a list or generator
expression instead.

Probably my single most common usage of map is:

    
    
        s = sep.join(map(str, parts))
    

because join() refuses to join anything that isn't a str, and map is a nice
way to stringify all elements of a list.

~~~
scardine
The alternative would be:

    
    
        s = sep.join([str(part) for part in parts])
    

I agree this is one of the cases where map looks nicer than list
comprehensions or generator expressions.

~~~
svisser
You can also use a generator expression so you don't have to create a list:

    
    
        s = sep.join(str(part) for part in parts)

------
nvie81
I've written a follow-up blog post here, hopefully providing another
perspective:

[http://nvie.com/posts/beautiful-map/](http://nvie.com/posts/beautiful-map/)

------
PhantomGremlin
No comments yet about why in Python 3 the map behavior changed when the
iterables are of different lengths? That seems like a gratuitous change. How
is that better (not just different) than what Python 2 did?

Also, there was one other change in Python 3 that should have been left alone.
I'm stealing the meme from a previous poster on HN:

    
    
       Python 3 broke "Hello, World!"
    

Why? Why couldn't that "wart" have been left the way it was? Sometimes it's
smarter to _not_ change something, especially if that change breaks nearly
100% of existing programs.

~~~
_callcc
IIRC the change is related to the change in `iter` which in python2 returns
`None` after exhausting a list but in python3 will raise `StopIteration`.

Very annoying TBH. I had some really nice list chunking functions using `map`
on python2 that no longer work on python3.

------
accounthere

        map(lambda x: x, ['a', 'b', 'c'], [1, 2])
    

This should be

    
    
         map(lambda x, y: (x, y), ['a', 'b', 'c'], [1, 2])
    

If you want the same behavior as passing None as the first argument.

------
hurin
> but I hope none of pythonistas will use it and one day it will be removed
> from the language.

This behaviour for map with None is no longer present in python3 and raises a
TypeError.

------
est
I am surprised nobody mentioned this yet.

    
    
         filter(None, [0 1, 2, 3, False, None, 5, 6, 7])
    

Here None is the same as bool()

