Skip to content Skip to sidebar Skip to footer

Trying To Understand Lambda

When I do dict = {'Alice': '7898', 'Beth': '9102', 'Cecil': '3258'} print filter(lambda x: x, dict['Alice']) it shows: 7898 When I do the next dict = {'Alice': '2341', 'Beth': '9

Solution 1:

filter() does the following: given a function and an iterable (like a list, tuple, etc), passes each item in the list to a function. For each item, the function returns a boolean true or false. If the function returns true on an item, the item is added to a new list.

When filter is finished, it returns the new list with all of the selected items. This allows you to "filter" through a list based on a criteria and select only the items matching the criteria.

A tricky thing is happening here. filter() loops through any iterable. This includes a string. When you pass dict['Alice'] as the object to iterate, it's passing '2341', and running the filter on each character in the string. You could break the filter's logic down as follows:

def matches(x):
    return x =='2341'result=''forcharin x:
    if matches(char):
         result+=char

print result

This doesn't work, because none of your individual characters equal '2341'.

Solution 2:

It looks like your misunderstanding is with filter, to me. You pass a predicate function and an iterable object to filter. It creates a new object containing those items from the first iterable for which the predicate returns a true value (not necessarily True itself, just something that tests as true). The iterable in the two cases is the string '2341', which means the individual letters are tested. Of course the string '2341' is not equal to any of '2', '3', '4', or '1'.

Try it with a tuple and it's easier to see what's going on:

>>> tup = tuple(dict['Alice'])
>>> tup
('7', '8', '9', '8')
>>> filter(lambda x: x, tup)
('7', '8', '9', '8')
>>> tup
('7', '8', '9', '8')
>>> filter(lambda x: x, tup)
('7', '8', '9', '8')
>>> filter(lambda x: x=="2341", tup)
()

Solution 3:

Do you want to test if the entry for 'Alice' is '2341'. You can do so via

printdict['Alice'] == '2341'

The issue you are facing is not with the lambda form but with the method filter which is not appropriate in this use case.

In general a lambda form is more or less nothing else than an anonymous function (see e.g. here).

Solution 4:

If you just want to call the lambda function you just use it like a function:

print (lambda x: x=="2341")(dict["Alice"])

This gives the expected result (true).

When you use filter, it treats its second argument as a list, so "2341" is treated as a list of characters ['2', '3', '4', '1'], none of which equals "2341".

Interesting thing I just found out: Python 3 returns filter objects from the filter() function, so the proper use of filter becomes

print( list( filter( lambda x: x, dict['Alice'] ) ) )

And that returns ['2', '3', '4', '1'] which would have avoided the initial confusion.

Solution 5:

Normally, one would apply filter to two arguments:

  1. a function
  2. a list (or other iterable object)

filter applies the function to each object in the list and return a list of all the objects for which the function returned True.

In your second example, your first argument is a function, as expected. But your second argument is not a list — it is a string "2341" (the result of looking up "Alice" in the dictionary).

(Edit: I got this next part wrong initially. Thanks to other posters for getting it right.) Filter treats the string like a list, applying the function to each character and keeping only those characters for which it returned True (none of them), resulting in an empty string. Now if you look back at your first example, it has the same problem, and it is only (bad?) luck that the answer was what you expected.

As another poster suggested, perhaps you want to apply your function more directly. In the first example:

(lambda x: x)(dict['Alice'])

In the second example:

(lambda x: x=="2341")(dict['Alice'])

Post a Comment for "Trying To Understand Lambda"