Hao*_*Tan 26 python list-comprehension
我有一个方法,可以获取一个列表并返回一个对象
# input a list, returns an object
def map_to_obj(lst):
a_list = f(lst)
return a_list[0] if a_list else None
Run Code Online (Sandbox Code Playgroud)
我想获得一个包含所有未映射的元素的列表None.
像这样:
v_list = [v1, v2, v3, v4]
[map_to_obj(v) for v in v_list if map_to_obj(v)]
Run Code Online (Sandbox Code Playgroud)
但是map_to_obj在列表推导中调用该方法两次似乎并不好.
有没有办法在列表推导中使用局部变量,以便它可以有更好的性能?
或者编译器是否自动优化它?
这就是我想要的:
(sml like)
[let mapped = map_to_obj(v) in for v in v_list if mapped end]
Run Code Online (Sandbox Code Playgroud)
Lyi*_*Dog 52
使用嵌套列表理解:
[x for x in [map_to_obj(v) for v in v_list] if x]
或者更好的是,围绕生成器表达式的列表理解:
[x for x in (map_to_obj(v) for v in v_list) if x]
从开始Python 3.8,并引入赋值表达式(PEP 572)(:=运算符),可以在列表推导中使用局部变量,以避免调用同一函数两次:
在我们的例子中,我们可以在使用表达式的结果来过滤列表时将的评估命名map_to_obj(v)为变量o。并因此o用作映射值:
[o for v in [v1, v2, v3, v4] if (o := map_to_obj(v))]
Run Code Online (Sandbox Code Playgroud)
您可以使用内置的python来避免重新计算filter:
list(filter(lambda t: t is not None, map(map_to_obj, v_list)))
Run Code Online (Sandbox Code Playgroud)
可以通过作弊并使用额外的“for”在推导式中设置局部变量,“for”“迭代”包含局部变量所需值的 1 元素元组。这是使用这种方法解决OP问题的方法:
[o for v in v_list for o in (map_to_obj(v),) if o]
Run Code Online (Sandbox Code Playgroud)
这里,o局部变量被设置为等于map_to_obj(v)每个v。
在我的测试中,这比 Lying Dog 的嵌套生成器表达式稍快(也比 OP 的双重调用要快,令人惊讶的是,如果函数不太慢的map_to_obj(v)话,它可能比嵌套生成器表达式更快)。map_to_obj
小智 5
变量赋值只是单数绑定:
[x for v in l for x in [v]]
Run Code Online (Sandbox Code Playgroud)
这是一个更一般的答案,也更接近您的建议。因此,对于您的问题,您可以编写:
[x for v in v_list for x in [map_to_obj(v)] if x]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
19578 次 |
| 最近记录: |