使用map()处理列表时,我想在lambda内访问该项目的索引。我怎样才能做到这一点?
例如
ranked_users = ['jon','bob','jane','alice','chris']
user_details = map(lambda x: {'name':x, 'rank':?}, ranked_users)
在上面的示例中,如何获取每个用户的排名?
Answers:
使用枚举:
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。我的第一个答案是
user_details = map(lambda (i,x): {'name':x, 'rank':i}, enumerate(ranked_users))
我强烈建议使用列表理解或发电机表达过map和lambda只要有可能。列表理解更具可读性,并且往往更快地启动。
enumerate生成元组(单个对象)。
lambdas不能像列表推导那样解压元组。
或者,您可以使用列表推导而不是map()和lambda。
ranked_users = ['jon','bob','jane','alice','chris']
user_details = [{'name' : x, 'rank' : ranked_users.index(x)} for x in ranked_users]
输出:
[{'name': 'jon', 'rank': 0}, {'name': 'bob', 'rank': 1}, {'name': 'jane', 'rank': 2}, {'name': 'alice', 'rank': 3}, {'name': 'chris', 'rank': 4}]
List内涵是非常强大的,也快比的组合map和lambda。
list.index() 仅在以下情况下才适用: ranked_users都是唯一的。给定ranked_users = ['chris','chris'] user_details输出[{'name': 'chris', 'rank': 0}, {'name': 'chris', 'rank': 0}]应在的位置[{'name': 'chris', 'rank': 0}, {'name': 'chris', 'rank': 1}]。
在我看来,问题在于地图功能,而首选答案是部分正确的,这是由于将元组参数放入lambda导致语法错误 lambda (i,x)
枚举的想法很好,正确的解决方案是:
map(lambda x: {'name':x[1], 'rank':x[0]}, enumerate(ranked_users))
以及一些比较速度和理解力的时间:
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))
测试结果:在此测试案例中,列表理解比map快约1.31倍