164

Suppose I have a list like:

mylis = ['this is test', 'another test']

How do I apply a function to each element in the list? For example, how do I apply str.upper to get:

['THIS IS TEST', 'ANOTHER TEST']
cottontail
  • 10,268
  • 18
  • 50
  • 51
shantanuo
  • 31,689
  • 78
  • 245
  • 403
  • Although OP would not have had any idea about list comprehensions, I added the tag in the hope that it makes it easier for duplicate closers to find the question. – Karl Knechtel Jul 08 '22 at 19:26
  • 1
    @shantanuo are you the one voting to close similar and older questions to your own? That would make this post the duplicate. – Eric Herlitz Oct 04 '22 at 21:38
  • @EricHerlitz I closed many questions as a duplicate of this one because it was originally the best I could find for the purpose. However, I was still unsatified, and today after perhaps years of frustration I prepared a more useful canonical from scratch. – Karl Knechtel Mar 07 '23 at 20:01

4 Answers4

182

Try using a list comprehension:

>>> mylis = ['this is test', 'another test']
>>> [item.upper() for item in mylis]
['THIS IS TEST', 'ANOTHER TEST']
Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
176

Using the built-in standard library map:

>>> mylis = ['this is test', 'another test']
>>> list(map(str.upper, mylis))
['THIS IS TEST', 'ANOTHER TEST']

In Python 2.x, map constructed the desired new list by applying a given function to every element in a list.

In Python 3.x, map constructs an iterator instead of a list, so the call to list is necessary. If you are using Python 3.x and require a list the list comprehension approach would be better suited.

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
mdml
  • 22,442
  • 8
  • 58
  • 66
9

Sometimes you need to apply a function to the members of a list in place. The following code worked for me:

>>> def func(a, i):
...     a[i] = a[i].lower()
>>> a = ['TEST', 'TEXT']
>>> list(map(lambda i:func(a, i), range(0, len(a))))
[None, None]
>>> print(a)
['test', 'text']

Please note, the output of map() is passed to the list constructor to ensure the list is converted in Python 3. The returned list filled with None values should be ignored, since our purpose was to convert list a in place

efimp
  • 209
  • 3
  • 2
  • 3
    A suggestion: don't create a list filled with `None`s only to throw it away immediately, use `any` instead of `list` around `map`. Also, use `range` with only one argument, the range will start from 0, same as list indices. Final result: `any(map(lambda i:func(a, i), range(len(a))))`. This expression will return `False` , but that can be ignored. – ack Mar 19 '21 at 18:49
  • @ack Your suggestion is good where you care about the status of each element (e.g. you really do want to check if any of the results are not `None`) but not sure why else you would want to go to the trouble of looping through the `None`s to check them, only to throw away a different result? This is only an consideration when using the interpreter. – scign Jan 24 '22 at 20:32
  • We could also use a generator expression instead of `map`. But really, rather than creating a mutating function that has to index back into the list, and providing it with the indices, it would be much cleaner to replace the list contents by slice assignment. – Karl Knechtel Aug 18 '22 at 20:07
1

String methods in Python are optimized, so you'll find that the loop implementations mentioned in the other answers here (1, 2) to be faster than vectorized methods in other libraries such as pandas and numpy that perform the same task.

In general, you can apply a function to every element in a list using a list comprehension or map() as mentioned in other answers here. For example, given an arbitrary function func, you can either do:

new_list = [func(x) for x in mylis]
# or 
new_list = list(map(func, mylis))

If you want to modify a list in-place, you can replace every element by a slice assignment.

# note that you don't need to cast `map` to a list for this assignment
# this is probably the fastest way to apply a function to a list 
mylis[:] = map(str.upper, mylis)
# or
mylis[:] = [x.upper() for x in mylis]

or with an explicit loop:

for i in range(len(mylis)):
    mylis[i] = mylis[i].upper()

You can also check out the built-in itertools and operator libraries for built-in methods to construct a function to apply to each element. For example, if you want to multiply each element in a list by 2, you can use itertools.repeat and operator.mul:

from itertools import repeat, starmap
from operator import mul

newlis1 = list(map(mul, mylis, repeat(2)))
# or with starmap
newlis2 = list(starmap(mul, zip(mylis, repeat(2))))

# but at this point, list comprehension is simpler imo
newlis3 = [x*2 for x in mylis]
cottontail
  • 10,268
  • 18
  • 50
  • 51