Hacker News new | ask | show | jobs
by Marat_Dukhan 3347 days ago
Because Python 2.7 is, IMO, a better language than Python 3+, e.g.:

- I like lambda a, b: a + b syntax better than lambda a_b: a_b[0] + a_b[1]

- I prefer map/reduce/filter to return lists rather than iterable

- I prefer dict.keys/values/items to return sets/lists rather than iterables, unless I call dict.iter[keys/values/items]

5 comments

> I like lambda a, b: a + b syntax better than lambda a_b: a_b[0] + a_b[1]

It already works this way.

    Python 3.6.1 (v3.6.1:69c0db5, Mar 21 2017, 17:54:52) [MSC v.1900 32 bit (Intel)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> add = lambda a, b: a + b
    >>> add(1, 2)
    3
> I prefer map/reduce/filter to return lists rather than iterable

You can produce a list from any iterable by passing it to `list()`. You cannot take a materialized list and make it lazy though.

> I prefer dict.keys/values/items to return sets/lists rather than iterables, unless I call dict.iter[keys/values/items]

Why? Sets are mutable. What happens when you mutate dict.values? It doesn't make sense.

lambda a, b: a + b kind of works, but you can't call it with tuple argument (which you could in Python 2.7). This hurts when e.g. you have a list of pairs and try to map when via lambda, e.g.: map(lambda a, b: a+b, [(1, 2), (3, 4)]). Even worse, this won't fail right away in Python 3 (thanks, lazy evaluation in map), but will raise when you try to use the result of map
That doesn't work in the python 2.7 that I'm running, just like python 3 it complains that I don't have enough arguments.
Right, needs brackets: lambda (a, b)
As far as I can tell, you're complaining about one character. This works.

    >>> add = lambda a, b: a + b
    >>> t = (1, 2)
    >>> add(*t)
    3
Is that extra asterisk the problem? Again, if you want a materialized list, pass it to `list()`. Projection failures will raise then.
Yes, sets are mutable, but if I call dict.keys, I expect to get a copy of keys.
Your first point is incorrect, lambda works with the first syntax for both python 2 and 3. What /has/ changed, however, is the implicit destructuring:

    l = lambda (a, b): a + b
    l((1, 2))
I suspect there are very good reasons not to allow something like this.

With regard to the second point, I also would have liked a more "gradual" step there, I find myself (especially in REPL environments) often doing `list(map(sth, sth))`. A `mapi`, `filteri` or something like this would probably not be zenny enough.

Both don't pose very strong points for python 2 > 3.

PEP 3113 -- Removal of Tuple Parameter Unpacking http://legacy.python.org/dev/peps/pep-3113/

These seem like OK reasons, but I find myself continuously needing the destructuring idiom in lambdas, while these introspection and documentation concerns are just not there for me.

However tuple-parameters being an exception to rules (such as args and kwargs not being usable with them) is more compelling. And allowing destructuring only in lambdas would be weird, because they wouldn't be normal function objects any more.

Unless the destructuring was only syntactic sugar for the translation in the PEP? But that's again inconsistent.

Yes, lack of implicit tuple unpacking in lambda is what forces me to write `lambda a_b`.

Python 2.7 has imap and ifilter in itertools. Python 3 could have imported them into global namespace to simplify usage without breaking map/filter functions.

>I find myself (especially in REPL environments) often doing `list(map(sth, sth))`.

This. I wonder if you could have a switch to make ipython print out the list instead of the iterator object at the REPL.

> I like lambda a, b: a + b syntax better than lambda a_b: a_b[0] + a_b[1]

uh, `lambda a,b: a + b` works in 3.6...

> I prefer ... to return lists rather than iterable:

Why? I'm just curious. Iterables are much more flexible than lists, unless you need random access... at which point list(...) works pretty well.

he mean `map(lambda (a, b): a+b, [(1, 2), (3, 4)])`
Iterables are so much better on memory though.

I wonder why isn't "lambda (a, b): a+b" allowed?

It was removed for reasons outlined in this PEP: http://legacy.python.org/dev/peps/pep-3113/
> - I like lambda a, b: a + b syntax better than lambda a_b: a_b[0] + a_b[1]

That works perfectly well in Python 3, you're thinking about `lambda (a, b)` aka `def foo((a, b))` aka tuple-parameter unpacking.

> - I prefer map/reduce/filter to return lists rather than iterable

1. why? 2. just wrap them in a list() call?

> - I prefer dict.keys/values/items to return sets/lists rather than iterables, unless I call dict.iter[keys/values/items]

You are aware that Python3's keyviews and itemsviews are sets but P2's are just lists right?