Python:如果f(x)不为空,则list_of_tuples中的(x,y)为[(x,y)]

use*_*710 1 python filtering tuples list-comprehension

我有以下格式的元组列表:

input_list = [(x1, y1), (x2, y2), ... , (xn, yn)]
Run Code Online (Sandbox Code Playgroud)

我想通过在每个元组的第一个参数上应用一个函数并将其存储在不同的元组列表中,将此列表转换为另一个列表.所以:

new_list = [(func(x), y) for (x, y) in input_list]
Run Code Online (Sandbox Code Playgroud)

问题是,func(x)可能会返回一个空字符串.在那种情况下,我不希望元组(func(x), y)进入new_list.我希望我可以这样做:

new_list = [(func(x), y) for (x, y) in input_list if func(x)]
Run Code Online (Sandbox Code Playgroud)

但这会导致计算量增加一倍,而且效率非常低.我怎么能做到这一点?

Mar*_*ers 9

可以使用常规for循环:

new_list = []
for x, y in input_list:
    result = func(x)
    if result:
        new_list.append((result, y))
Run Code Online (Sandbox Code Playgroud)

如果您坚持使用单行列表理解,您可以使用:

[(res, y) for x, y in input_list for res in (func(x),) if res]
Run Code Online (Sandbox Code Playgroud)

其中单元素元组上的嵌套循环为您提供对函数输出的引用.然而,这将需要另外3行评论向未来的维护者解释你到底在那里拉什么,因此显式循环(在我看来)是更好的选择.

第三种选择是嵌入一个生成器表达式,首先转换输入:

[(res, y) for res, y in ((func(x), y) for x, y in input_list) if res]
Run Code Online (Sandbox Code Playgroud)

这对于可能不值得的维护者而言可能需要认知上的飞跃.


Rem*_*ich 5

分两步完成。无需构建中间列表,生成器表达式就足够了:

computed_values = ((func(x), y) for (x, y) in list)
filtered_values = [(x, y) for (x, y) in computed_values if x != '']
Run Code Online (Sandbox Code Playgroud)

  • @ user991710:但是,转换会在迭代生成器表达式时发生。它实现了与我在答案中命名的所有3种方法相同的效果,最后一种方法与该方法基本相同,但是内联了`computed_values`。 (2认同)