Python Cheat Sheet: Lambdas

Did you think that list comprehensions were a complicated thing? I suspect you’ll think again about complicated things in Python while reading this text.

Lambdas

By definition, lambdas are short functions defined in place, used for small data processing tasks. There are 2 reasons on why they should be used:

  • Execution speed – they can be optimized by compilers, first by removing an actual function call, next by opening the door for more optimizations through any possible internal (by the compiler) code re-arrangement;

  • Writing less code.

A Python example of a n square lambda:

g = lambda x: x ** 2	# e.g. g(3) yields a value of 9

Lambdas are usually used in conjunction with data processing functions such as filter, map and reduce.

Filtering

If we want to select only a portion of some input, the filter function comes to its best use in combination with a lambda:

print filter(lambda x: x % 2 == 0, xrange(0, 11))
...
[0, 2, 4, 6, 8, 10]
Transformation

Applying a transformation function to the entire input is a job for map:

print map(lambda x: x * 2, xrange(0, 11))
...
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
Summarizing

Processing the entire input in order to get a single final result is a job for reduce. Please note that 2 arguments are required for the lambda function used for processing; the first 2 elements are used in the beginning, then the lambda result and the next element are used until the input is exhausted.

print reduce(lambda x, y: x + y, xrange(0, 11))
...
55	# 1 + 2 + ... + 10

Now for some serious stuff:

MapReduce in Python
print reduce(lambda x, y: x + y, map(lambda x: x * 2, xrange(0, 11)))
...
110	# 1*2 + 2*2 + ... + 10*2
The intersection of 2 lists
def intersection(A, B):
  S = set(A)
  return filter(lambda x: x in S, B)

Such answer will probably not be expected in an interview setting. If you find yourself in an interview, before writing such thing down, please be sure that you can explain what’s going on (e.g. in big O notation, how set works).

Removing duplicates from a list

If the order of the remaining unique elements does not matter, a set(A) call is enough. Otherwise we have to get creative:

def dedup(A):
  S = set()
  return filter(lambda x: x not in S and None == S.add(x), A)

The add method of set always returns None and this evaluates to boolean False. In order to get things straight, a small hack was required (S.add() == None).

Also, please note that the solution above returns the first element that it finds (the other duplicates are rejected). Solutions for returning the last or the nth duplicate in the sequence do exist, but they’re far easier to code if the element order in the result is not significant:

def dedup_last_unordered(A):
  S = set()
  map(lambda x: ((x in S and None == S.remove(x)) or True) and None == S.add(x), A)
  return S

As you can see, we’re getting close to exceeding the purpose of lambda functions with the above solution. A “normal” way to code may be much clearer:

def dedup_last_unordered(A):
  S = set()
  for i in A:
    if i in S:
      S.remove(i)
    S.add(i)
  return S

The solution for the nth duplicate cannot be completely written with lambdas because a counter must be assigned / incremented and such operation is not allowed inside lambdas. A “normal” solution requires defining a dictionary and keeping the counter in the value field, but I believe it’s better to call it a day.


That’s it for today, hope you enjoyed it!

Leave a Reply

Your email address will not be published. Required fields are marked *