Can I use index information inside the map function?
Question:
Let’s assume there is a list a = [1, 3, 5, 6, 8]
.
I want to apply some transformation on that list and I want to avoid doing it sequentially, so something like map(someTransformationFunction, a)
would normally do the trick, but what if the transformation needs to have knowledge of the index of each object?
For example let’s say that each element must be multiplied by its position. So the list should be transformed to a = [0, 3, 10, 18, 32]
.
Is there a way to do that?
Answers:
You can use enumerate()
:
a = [1, 3, 5, 6, 8]
answer = map(lambda (idx, value): idx*value, enumerate(a))
print(answer)
Output
[0, 3, 10, 18, 32]
Use the enumerate()
function to add indices:
map(function, enumerate(a))
Your function will be passed a tuple, with (index, value)
. In Python 2, you can specify that Python unpack the tuple for you in the function signature:
map(lambda (i, el): i * el, enumerate(a))
Note the (i, el)
tuple in the lambda argument specification. You can do the same in a def
statement:
def mapfunction((i, el)):
return i * el
map(mapfunction, enumerate(a))
To make way for other function signature features such as annotations, tuple unpacking in function arguments has been removed from Python 3.
Demo:
>>> a = [1, 3, 5, 6, 8]
>>> def mapfunction((i, el)):
... return i * el
...
>>> map(lambda (i, el): i * el, enumerate(a))
[0, 3, 10, 18, 32]
>>> map(mapfunction, enumerate(a))
[0, 3, 10, 18, 32]
To extend Martijn Pieters’ excellent answer, you could also use list comprehensions in combination with enumerate
:
>>> a = [1, 3, 5, 6, 8]
>>> [i * v for i, v in enumerate(a)]
[0, 3, 10, 18, 32]
or
[mapfunction(i, v) for i, v in enumerate(a)]
I feel list comprehensions are often more readable than map
/lambda
constructs. When using a named mapping function that accepts the (i, v)
tuple directly, map
probably wins though.
To make compatible with Python3
def map_fn(data):
idx, el = data
return idx*el
my_list = [2,3,5,7]
print(list(map(map_fn, list(enumerate(my_list)))))
# Python3
map(lambda args: print(args[0],args[1]) ,enumerate(a_list))
# use arg list, just get the result with index
# Python2
map(lambda index,content: print(index,content) ,enumerate(a_list))
Just a heads up that in python 3 the enumerate is not how it’s written anymore
Let’s assume there is a list a = [1, 3, 5, 6, 8]
.
I want to apply some transformation on that list and I want to avoid doing it sequentially, so something like map(someTransformationFunction, a)
would normally do the trick, but what if the transformation needs to have knowledge of the index of each object?
For example let’s say that each element must be multiplied by its position. So the list should be transformed to a = [0, 3, 10, 18, 32]
.
Is there a way to do that?
You can use enumerate()
:
a = [1, 3, 5, 6, 8]
answer = map(lambda (idx, value): idx*value, enumerate(a))
print(answer)
Output
[0, 3, 10, 18, 32]
Use the enumerate()
function to add indices:
map(function, enumerate(a))
Your function will be passed a tuple, with (index, value)
. In Python 2, you can specify that Python unpack the tuple for you in the function signature:
map(lambda (i, el): i * el, enumerate(a))
Note the (i, el)
tuple in the lambda argument specification. You can do the same in a def
statement:
def mapfunction((i, el)):
return i * el
map(mapfunction, enumerate(a))
To make way for other function signature features such as annotations, tuple unpacking in function arguments has been removed from Python 3.
Demo:
>>> a = [1, 3, 5, 6, 8]
>>> def mapfunction((i, el)):
... return i * el
...
>>> map(lambda (i, el): i * el, enumerate(a))
[0, 3, 10, 18, 32]
>>> map(mapfunction, enumerate(a))
[0, 3, 10, 18, 32]
To extend Martijn Pieters’ excellent answer, you could also use list comprehensions in combination with enumerate
:
>>> a = [1, 3, 5, 6, 8]
>>> [i * v for i, v in enumerate(a)]
[0, 3, 10, 18, 32]
or
[mapfunction(i, v) for i, v in enumerate(a)]
I feel list comprehensions are often more readable than map
/lambda
constructs. When using a named mapping function that accepts the (i, v)
tuple directly, map
probably wins though.
To make compatible with Python3
def map_fn(data):
idx, el = data
return idx*el
my_list = [2,3,5,7]
print(list(map(map_fn, list(enumerate(my_list)))))
# Python3
map(lambda args: print(args[0],args[1]) ,enumerate(a_list))
# use arg list, just get the result with index
# Python2
map(lambda index,content: print(index,content) ,enumerate(a_list))
Just a heads up that in python 3 the enumerate is not how it’s written anymore