Getting index of item while processing a list using map in python

Python

Python Problem Overview


While processing a list using map(), I want to access index of the item while inside lambda. How can I do that?

For example

ranked_users = ['jon','bob','jane','alice','chris']
user_details = map(lambda x: {'name':x, 'rank':?}, ranked_users)

How can I get rank of each user in above example?

Python Solutions


Solution 1 - Python

Use enumerate:

In [3]: user_details = [{'name':x, 'rank':i} for i,x in enumerate(ranked_users)] 

In [4]: user_details
Out[4]: 
[{'name': 'jon', 'rank': 0},
 {'name': 'bob', 'rank': 1},
 {'name': 'jane', 'rank': 2},
 {'name': 'alice', 'rank': 3},
 {'name': 'chris', 'rank': 4}]

PS. My first answer was

user_details = map(lambda (i,x): {'name':x, 'rank':i}, enumerate(ranked_users))

I'd strongly recommend using a list comprehension or generator expression over map and lambda whenever possible. List comprehensions are more readable, and tend to be faster to boot.

Solution 2 - Python

Alternatively you could use a list comprehension rather than map() and lambda.

ranked_users = ['jon','bob','jane','alice','chris']
user_details = [{'name' : x, 'rank' : ranked_users.index(x)} for x in ranked_users]

Output:

[{'name': 'jon', 'rank': 0}, {'name': 'bob', 'rank': 1}, {'name': 'jane', 'rank': 2}, {'name': 'alice', 'rank': 3}, {'name': 'chris', 'rank': 4}]

List comprehensions are very powerful and are also faster than a combination of map and lambda.

Solution 3 - Python

In my opinion the question was about map function and preferred answer is partly correct due to syntax error caused by putting tuple argument to lambda lambda (i,x)

idea of enumerate is nice and proper solution would be:

map(lambda x: {'name':x[1], 'rank':x[0]}, enumerate(ranked_users))

and some timing to compare speed with comprehension:

def with_map():
    ranked_users = range(10 ** 6)
    list(map(lambda x: {'name': x[1], 'rank': x[0]}, enumerate(ranked_users)))

def by_comprehension():
    ranked_users = range(10 ** 6)
    [{'name': x, 'rank': i} for i, x in enumerate(ranked_users)]

from timeit import timeit
time_with_map = timeit(with_map, number=10)
time_with_comprehension = timeit(by_comprehension, number=10)

print('list comprehension is about %.2f x faster than map in this test case' % (time_with_map/time_with_comprehension))

test result: list comprehension is about 1.31 x faster than map in this test case

Solution 4 - Python

Actually here is a more elegant, verbose solution than using an enumerate tuple in the map (because of tuple indexing). Map can take more iterables as arguments so let's use it.

map(lambda user, user_id: (user_id, user), ranked_users, range(ranked_users.__len__()))

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJayeshView Question on Stackoverflow
Solution 1 - PythonunutbuView Answer on Stackoverflow
Solution 2 - PythonPrydieView Answer on Stackoverflow
Solution 3 - Pythoncheshire catView Answer on Stackoverflow
Solution 4 - PythonxbalajView Answer on Stackoverflow