pythonlambdaprogramming-languageskeyword

Shorter alternative for 'lambda' keyword?


Background:

Python is about simplicity and readable code. It has gotten better over the versions and I am a huge fan! However, typing l a m b d a every time I have to define a lambda is not fun (you may disagree). The problem is, these 6 characters -- l a m b d a -- make my statements longer, especially when I nest a couple of lambdas inside maps and filters. I am not nesting more than two, because it takes away the readability of python, even then, typing l a m b d a twice feels too verbose.

The actual question (is in comments):

# How to rename/alias a keyword to a nicer one? 
lines = map(lmd x: x.strip(), sys.stdin)

# OR, better yet, how to define my own operator like -> in python?
lines = map(x -> x.strip(), sys.stdin)
# Or may be :: operator is pythonic
lines = map(x :: x.strip(), sys.stdin)

# INSTEAD of this ugly one. Taking out this is my goal!
lines = map(lambda x: x.strip(), sys.stdin)

I am happy to add import like this:

from myfuture import lmd_as_lambda
# OR
from myfuture import lambda_operator

Solution

  • The good news is: You don't need to use map or filter at all, you can use generator expressions (lazy) or list comprehensions (eager) instead and thus avoid lambdas completely.

    So instead of:

    lines = map(lambda x: x.strip(), sys.stdin)
    

    Just use:

    # You can use either of those in Python 2 and 3, but map has changed between
    # Python 2 and Python 3 so I'll present both equivalents:
    lines = (x.strip() for x in sys.stdin)  # generator expression (Python 3 map equivalent)
    lines = [x.strip() for x in sys.stdin]  # list comprehension   (Python 2 map equivalent)
    

    It's probably also faster if you use comprehensions. Very few functions are actually faster when used in map or filter - and using a lambda there is more of an anti-pattern (and slow).


    The question only contained an example for map, but you can also replace filter. For example if you want to filter out odd numbers:

    filter(lambda x: x%2==0, whatever)
    

    You can use a conditional comprehension instead:

    (x for x in whatever if x%2==0)
    [x for x in whatever if x%2==0]
    

    You could even combine a map and filter in one comprehension:

    (x*2 for x in whatever if x%2==0)
    

    Just consider how that would look like with map and filter:

    map(lambda x: x*2, filter(lambda x: x%2==0, whatever))
    

    Note: That doesn't mean lambda isn't useful! There are lots of places where lambdas are very handy. Consider the key argument for sorted (and likewise for min and max) or functools.reduce (but better keep away from that function, most of the times a normal for-loop is more readable) or itertools that require a predicate function: itertools.accumulate, itertools.dropwhile, itertools.groupby and itertools.takewhile. Just to name a few examples where a lambda could be useful, there are probably lots of other places as well.