简体   繁体   中英

Using map and filter function on a sublist in python

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)

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]]

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]]

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]

您可以在过滤器函数中使用None参数,并执行类似的操作

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM