Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Most times you are interested in doing the simple, e.g.:

  filtered = [x for x in seq if x>10]
Python's list comprehension is much more readable than using map/filter/reduce - at least for Python programmers :) Anyhow, I really like Guido's decision on dropping these - it creates a cleaner language and forces people to think Pythonic when programming in Python.


> Python's list comprehension is much more readable than using map/filter/reduce - at least for Python programmers

For simple cases, yes. But I wouldn't say

    [each for each in [expensive_call(x) for x in seq] if cond(each)]
is more readable than

    filter(cond, map(expensive_call, seq))
at least for functional-thinking minds. The level of thinking in abstract is different here.

Now the problem is, some people see Python as a very functional language (with first-class functions etc) and want to use it that way (like Lisp), but BDFL and some core Python devs believe it is better to keep it Pythonic, thus those functional people are kinda pissed off by this and switch away from Python.

Personally I don't think it will make Python a lot cleaner to remove two auxiliary functions and force people to use list comprehension when it is completely trivial to add these missing pair back (two lines of code).

(disclosure: I prefer FP, but I also think keeping things Pythonic is fine most of the time. It's just that in this case, I think map/filter is pretty "Pythonic" according to me. :)


At first, I thought "wow, Python generator expressions are really ugly nested". This is especially true after working with C#3/Linq because query expressions have natural places for line breaks and read in a more consistent order.

Later, I ran into some cases where I wanted a multi-line lambda. And my thought was "aaragh134!#?!"

Then, a weird thing happened. I started making a conscious effort to follow PEP 8. 79 column limit? Seriously? That sucks. But after weeks of struggling with it, something finally hit me. I realized I was writing better code by forcing myself to reduce code density. Sure, it was a little bit longer, but I spend way more time reading it than writing it.

Stop trying to fight it; assign a name to that lambda. Readability counts.

Stop trying to be clever; assign a name to that inner expression. Flat is better than nested.


I know you all know this, but I feel like it bears mentioning that nobody is forcing you to use list comprehensions whether map/filter stay in Python's built-ins or not. They can be defined in around 3-4 lines of code each. Lisp aficionados, already accustomed to the bottom-up style of programming, ought to have no problem writing functions like these as necessary.


There's a difference between things being possible and being encouraged.

De-emphasizing functional operations makes it more likely for libraries to work in a non-functional style, for tutorials to do so, etc.

It's tiring fighting against a community and a (benevolent) dictator that disagree with you.


> It's tiring fighting against a community and a (benevolent) dictator that disagree with you.

That summarizes the problem I guess :D


If I remember correctly, "removing" these functions mostly just meant dumping them into the functools module rather than including them as a built in function.


Yeah I know. Maybe "force" is not the right word ... probably "discourage"?

Actually only one line of code is enough for each of map/filter:

    def map(fn, seq): return [fn(each) for each in seq]
    def filter(cond: seq): return [each for each in seq if cond(each)] 
But seriously, what do you really gain by removing these two? Isn't that too ideological? I don't really see how un-Pythonic it would be to use map/filter instead of list comprehensions. The problem is BDFL's attitude seems to drive many FP-ers away, like the guy in the original post.


They ultimately weren't removed. reduce was removed from the builtins, but it's still just one import away. From itertools import reduce.


Um...

    (filter #(> x 10) seq)
sure is readable for me, and I'm fluent in Python and various Lisps. (That example is Clojure.)

I would like to point out, however, that CL allows you to write:

    (loop for x in seq
          when (> x 10)
          collect x)
which you might think is verbose ("why do I need that 'collect'?")... except that loop allows you to write things like

    (loop for i in *random*
          counting (evenp i) into evens
          counting (oddp i) into odds
          summing i into total
          maximizing i into max
          minimizing i into min
          finally (return (list min max total evens odds)))
Loop knocks Python's trivial list comprehensions into a cocked hat.

I switch between map/filter and loop depending on whether I'm working with predefined functions (e.g., (filter 'less-than-ten seq)), handling multiple sequences, doing side-effects, etc.


>Loop knocks Python's trivial list comprehensions into a cocked hat.

CL could really use something like Python's generators though. The loop macro is an ugly hack in comparison.


[It] creates a cleaner language and forces people to think Pythonic when programming in Python.

The question is whether "Pythonic," as the community defines it today, is optimal in all cases. As an analogue, there have been enough talks about things the Java community considers to be stylistically optimal that look really horrible compared to implementations in other languages -- like Python. :-) Pythonic style should be a guide, not an edict, and should be deviated from or redefined when it makes sense. The examples riobard provided already show the syntax weighing things down, a situation where syntax should give way to a more functional style approach.

As for it creating a cleaner language, I try to approach this, as with all things, from the perspective of being an language-agnostic programmer. From that perspective, I do like the python syntax for simple things like what you defined, but under heavier weight mapping and filtering operations, the map/filter function call syntax seems a lot cleaner. There's nothing wrong with syntactic sugar, but I would assert that it will tend to suck when it is all you have.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: