Python:[(x,y)表示元组列表中的(x,y),如果f(x)不是空的]

Python:[(x,y)表示元组列表中的(x,y),如果f(x)不是空的],python,tuples,filtering,list-comprehension,Python,Tuples,Filtering,List Comprehension,我有以下格式的元组列表: input_list = [(x1, y1), (x2, y2), ... , (xn, yn)] 我想通过对每个元组中的第一个参数应用函数,并将其存储在不同的元组列表中,将此列表转换为不同的列表。因此: new_list = [(func(x), y) for (x, y) in input_list] 问题是,func(x)可能会返回一个空字符串。在这种情况下,我不希望元组(func(x),y)位于新列表中。我希望我能做一些事情,比如: new_list = [

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

input_list = [(x1, y1), (x2, y2), ... , (xn, yn)]
我想通过对每个元组中的第一个参数应用函数,并将其存储在不同的元组列表中,将此列表转换为不同的列表。因此:

new_list = [(func(x), y) for (x, y) in input_list]
问题是,
func(x)
可能会返回一个空字符串。在这种情况下,我不希望元组
(func(x),y)
位于
新列表中。我希望我能做一些事情,比如:

new_list = [(func(x), y) for (x, y) in input_list if func(x)]
但这将导致计算量加倍,效率极低。如何实现这一点?

您可以使用常规的
for
循环:

new_list = []
for x, y in input_list:
    result = func(x)
    if result:
        new_list.append((result, y))
如果您坚持一行列表理解,您可以使用:

[(res, y) for x, y in input_list for res in (func(x),) if res]
其中,单个元素元组上的嵌套循环提供对函数输出的引用。然而,这需要另外3行注释,向未来的维护人员解释你到底在做什么,因此显式循环(在我看来)是更好的选择

第三个选项是首先嵌入转换输入的生成器表达式:

[(res, y) for res, y in ((func(x), y) for x, y in input_list) if res]
对于维护人员来说,这同样可能需要一次认知上的飞跃,这可能不值得。

您可以使用常规的
for
循环:

new_list = []
for x, y in input_list:
    result = func(x)
    if result:
        new_list.append((result, y))
new_list = []
for (x, y) in old_list:
  new_x = func(x)
  if new_x: new_list.append((new_x, y))
如果您坚持一行列表理解,您可以使用:

[(res, y) for x, y in input_list for res in (func(x),) if res]
其中,单个元素元组上的嵌套循环提供对函数输出的引用。然而,这需要另外3行注释,向未来的维护人员解释你到底在做什么,因此显式循环(在我看来)是更好的选择

第三个选项是首先嵌入转换输入的生成器表达式:

[(res, y) for res, y in ((func(x), y) for x, y in input_list) if res]

这同样需要维护人员进行认知上的飞跃,但这可能不值得。

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

new_list = []
for (x, y) in old_list:
  new_x = func(x)
  if new_x: new_list.append((new_x, y))
computed_values = ((func(x), y) for (x, y) in list)
filtered_values = [(x, y) for (x, y) in computed_values if x != '']

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

computed_values = ((func(x), y) for (x, y) in list)
filtered_values = [(x, y) for (x, y) in computed_values if x != '']

[(x,y)for(x,y)in[(func(x,y)for(x,y)in list]如果x]
?@fredtantini我在想什么-只要把list comp改成gen exp…
[(x,y)for(x,y)in[(func(x,y)for(x,y)in list]如果x]
?@fredtantini我在想什么-只要把list comp改成gen exp…哇…那太可怕了。)很明显,我现在必须支持你的解决方案。类似的事情提醒我,我不是一个伟大的程序员,除非我能说“我可以用一个普通的
来进行
循环!”。谢谢你的详细和翔实的回答!哇……太可怕了。:)很明显,我现在必须支持你的解决方案。类似的事情提醒我,我不是一个伟大的程序员,除非我能说“我可以用一个普通的
来进行
循环!”。谢谢你的详细和翔实的回答!这是一种可能的方法,但我想避免在已经转换列表后必须对其进行过滤。@user991710:但转换是在迭代生成器表达式时进行的。它与我在回答中提到的所有3种方法都达到了相同的效果,最后一种方法基本上与这一种方法相同,但内联了
computed_值。@MartijnPieters啊,似乎我当时误解了他的回答。感谢您的澄清。这是一种可能的方法,但我想避免在已经转换列表后必须对其进行筛选。@user991710:但转换是在您迭代生成器表达式时进行的。它与我在回答中提到的所有3种方法都达到了相同的效果,最后一种方法基本上与这一种方法相同,但内联了
computed_值。@MartijnPieters啊,似乎我当时误解了他的回答。谢谢你的澄清。