How to apply a function to each sublist of a list in python?

18,000

Solution 1

You can use the builtin map to do this.

So if the function you want to apply is len, you would do:

>>> list_of_lists = [['how to apply'],['a function'],['to each list?']]
>>> map(len, list_of_lists)
[1, 1, 1]

In Python3, the above returns a map iterator, so you will need an explicit list call:

>>> map(len, list_of_lists)
<map object at 0x7f1faf5da208>
>>> list(map(len, list_of_lists))
[1, 1, 1]

If you are looking to write some code for this which has to be compatible in both Python2 and Python3, list comprehensions are the way to go. Something like:

[apply_function(item) for item in list_of_lists]

will work in both Python 2 and 3 without any changes.

However, if your input list_of_lists is huge, using map in Python3 would make more sense because the iterator will be much faster.

Solution 2

You can use a list comprehension, like this

[function_to_be_done(item) for item in list_of_lists]

For example,

>>> list_of_lists = [['how to apply'],['a function'],['to each list?']]
>>> [len(item) for item in list_of_lists]
[1, 1, 1]

Note: Though list comprehensions look like a way to apply a function to all the elements, its main purpose is to construct a new list. So, if you don't want to construct a new list, then just iterate with for loop and call the function.


Apart from that, you can use the map function in Python 2.7, to apply a function to all the elements and construct a list. For example,

>>> list_of_lists = [['how to apply'],['a function'],['to each list?']]
>>> map(len, list_of_lists)
[1, 1, 1]

But, map returns a map iterator object in Python 3.x. So, you need to explicitly convert that to a list, like this

>>> list_of_lists = [['how to apply'],['a function'],['to each list?']]
>>> map(len, list_of_lists)
<map object at 0x7f94026afd30>
>>> list(map(len, list_of_lists))
[1, 1, 1]

You might want to read about, what Guido thinks about map in this post.

Basically, map would more often demand you to create a new function (mostly people create a lambda function). But in many cases, list comprehension avoids that.

Solution 3

How about

[ F(x) for x in list_of_lists ]

which will iterate over list_of_lists, call F with each sublist as an argument, then generate a list of the results.

If you want to use the sublists as all the arguments to F you could do it slightly differently as

[ F(*x) for x in list_of_lists ]

Solution 4

Something that works on arbitrarily nested lists, e.g. [[1,2],[[5]],[7,[8,[9,11]]]] :

def apply_f(a,f):
 if isinstance(a,list):
     return map(lambda t:apply_f(t,f), a)
 else:
     return f(a)

here is an example of running this:

>>> ll=[[1,2],[[5]],[7,[8,[9,11]]]]
>>> apply_f(ll,lambda t:t**2)
[[1, 4], [[25]], [49, [64, [81, 121]]]]

and here is how to do the same only on selected levels:

def apply_f(a,f,depth,levels):
    if isinstance(a,list):
        return map(lambda t:apply_f(t,f,depth+1,levels), a)
    else:
        if depth in levels:
            return f(a)
        else:
            return a

getting e.g.

>>> apply_f(ll,lambda t:t**2, 0, [2,4])
[[1, 4], [[5]], [49, [8, [81, 121]]]]

there are some optimisations to do here, by avoiding passing f and levels around (making the recursive function an inner function in a wrapper, so that it can use f and levels from the outer scope), but that's minor. (Note that this is Python 2, for Python 3 you need to replace map with something else).


For a more generic input, the following would do the trick:

def apply_f(a,f):
    try: 
       return(f(a))
    except:
       return map(lambda t:apply_f(t,f), a)

So now also the following sort of works:

>> apply_f([(1,2),[[5]],[7,(8,[9,11])]],lambda t:t**2)
[[1, 4], [[25]], [49, [64, [81, 121]]]]

(things get slightly rewritten, as map() always produces lists...)

Solution 5

Map is your friend! map takes a function and an iterable (list, for example) and applies the function on each element of the list.

map(len, [['how to apply'],['a function'],['to each list?']]) 

Output

[1, 1, 1]

If you wanted to do more granular calculation on elements of the sublist, you can nest the map:

map(lambda x: map(lambda y: y + 1, x), [[1], [1, 2], [1, 2, 3]])

Output

[[2], [2, 3], [2, 3, 4]]

Another possible approach (also from functional programming) are list comprehensions. List comprehension is a way of constructing a list from iterable in Python. The syntax is [element for element in iterable]. Any computation can be done on the element, so

[f(element) for element in iterable]

means that the resulting list will be a list of elements, where each element is the result of function f. Like map, list comprehension can be further nested, resulting in a nested element function application.

[element + 1 for element in el] for el in [[1], [1, 2], [1, 2, 3]]]

Output

[[2], [2, 3], [2, 3, 4]]
Share:
18,000
skwoi
Author by

skwoi

Updated on July 23, 2022

Comments

  • skwoi
    skwoi almost 2 years

    Lets say I have a list like this:

    list_of_lists = [['how to apply'],['a function'],['to each list?']]
    

    And I have a function let's say I want to apply the F function to each sublist of the F function can compute some score about two lists. How can apply this F function to each list of list_of_lists and return each score in a new list like this:

    new_list = [score_1, score_2, score_3]
    

    I tried with the map function the following:

    map(F, list_of_lists).append(new_list)