99 votes

Obtenir l'index de l'élément lors du traitement d'une liste à l'aide de la carte en python

Lors du traitement d'une liste à l'aide de map(), je souhaite accéder à l'index de l'élément à l'intérieur de lambda. Comment puis je faire ça?

Par example

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

Comment puis-je obtenir le classement de chaque utilisateur dans l'exemple ci-dessus ?

137voto

unutbu Points 222216

Utiliser énumérer :

 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. Ma première réponse était

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

Je recommanderais fortement d'utiliser une compréhension de liste ou une expression de générateur sur map et lambda mesure du possible. Les compréhensions de liste sont plus lisibles et ont tendance à être plus rapides à démarrer.

13voto

Prydie Points 535

Alternativement, vous pouvez utiliser une compréhension de liste plutôt que map() et lambda.

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

Production:

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

Les compréhensions de liste sont très puissantes et sont également plus rapides qu'une combinaison de map et lambda .

10voto

cheshire cat Points 121

À mon avis, la question portait sur la fonction de carte et la réponse préférée est en partie correcte en raison d'une erreur de syntaxe causée par l'ajout de l'argument tuple à lambda lambda (i,x)

l'idée d'énumérer est agréable et la solution appropriée serait :

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

et un peu de temps pour comparer la vitesse avec la compréhension :

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

résultat du test : la compréhension de la liste est environ 1,31 x plus rapide que la carte dans ce cas de test

4voto

xbalaj Points 101

En fait, voici une solution plus élégante et plus détaillée que d'utiliser un tuple d'énumération dans la carte (à cause de l'indexation des tuples). Map peut prendre plus d'itérables comme arguments, alors utilisons-le.

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X