1
L = [[5, 0, 6], [7, 22], [0, 4, 2], [9, 0, 45, 17]]

I do have this list and my task is to remove the 0's. I have to use both map() and filter() function.

The hint is that this task is solvable with a single expression using map, filter and lambda expressions.

I have been trying to figure this out for quite a while but I just don't get it. You don't have to solve it completely, but help would be appreciated.

I assume I use map() to iterate over the outer lists, but how do I call filter() with the sublist?

L2 = map(lambda x: filter(lambda x: x<>0 ,L),L)
1
  • Ugh, sorry, getting kinda late here :< Commented Dec 10, 2017 at 23:03

4 Answers 4

2

Using map and filter you could write the following

>>> list(map(lambda i: list(filter(lambda i: i != 0, i)), L))
[[5, 6], [7, 22], [4, 2], [9, 45, 17]]

For what it's worth, I'd prefer a nested list comprehension

>>> [[i for i in j if i != 0] for j in L]
[[5, 6], [7, 22], [4, 2], [9, 45, 17]]
Sign up to request clarification or add additional context in comments.

Comments

1

The key to me is to think about types, which is a somewhat foreign concept in Python.

map takes a function and an iterable, and returns an iterable that is the result of applying that function to each element of the iterable argument.

map(f: "some function",
    lst: "some iterable") -> "(f(e) for e in lst)"

in this case, the elements of your outer lists are themselves lists! And you're planning to apply the filter function to each to remove the zeroes. filter expects a function (that itself expects an element, then returns True if that element should be in the result, or False if it should be removed) and a list of those elements.

filter(f: "some_func(e: 'type A') -> Bool",
       lst: "some_iterable containing elements of type A") ->
       "(e for e in lst if f(e))":

Your filter function then is just filter(lambda x: x != 0, some_list), or lambda sublst: filter(lambda x: x!=0, sublst). Apply that in the map and you'll get:

map(lambda sublst: filter(lambda x: x!=0, sublst), lst)

or

[[x for x in xs if x!=0] xs in xss]

This is much easier to express in Haskell, which deals with map and filter much more naturally.

map (filter (/=0)) lst
-- or still with a list comprehension
[[x | x <- xs, x!=0] | xs <- xss]

Comments

1

You can use the fact that if the first argument to filter() is None then only those items that are "true" will be retained. 0 is considered false, so 0 will be removed.

A solution can be written like this:

>>> L = [[5, 0, 6], [7, 22], [0, 4, 2], [9, 0, 45, 17]]
>>> map(lambda l: filter(None, l), L)
[[5, 6], [7, 22], [4, 2], [9, 45, 17]]

If you are using Python 3 then you can call list() on the result of the filter() and the map() to get the required list:

>>> map(lambda l: filter(None, l), L)
<map object at 0x7fb34856be80>
>>> list(map(lambda l: list(filter(None, l)), L))
[[5, 6], [7, 22], [4, 2], [9, 45, 17]]

Now that's getting less readable. A list comprehension is probably better.

>>> [[item for item in l if item] for l in L]
[[5, 6], [7, 22], [4, 2], [9, 45, 17]]

Comments

0

You can use None argument in filter function and do something like

[list(filter(None, i)) for i in a]

1 Comment

doesn't meet OP's map requirement

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.