【问题标题】:Python: [(x, y) for (x, y) in list_of_tuples if f(x) is not empty]Python: [(x, y) for (x, y) in list_of_tuples if f(x) is not empty]
【发布时间】:2014-12-05 13:17:32
【问题描述】:

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

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 中。我希望我可以这样做:

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

但这会导致计算量翻倍并且效率极低。我怎样才能做到这一点?

【问题讨论】:

  • [(x,y) for (x,y) in [(func(x), y) for (x, y) in list] if x] ?
  • @fredtantini 我在想什么 - 只需将 list-comp 转换为 gen-exp...

标签: python tuples filtering list-comprehension


【解决方案1】:

可以使用常规的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 循环!”之前,我并不是一个伟大的程序员。感谢您提供详细而翔实的答案!
【解决方案2】:

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

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

【讨论】:

  • 这是一种可能的方法,但我想避免在已经转换列表后过滤列表。
  • @user991710: 但是转换发生在迭代生成器表达式时。它实现了与我在答案中命名的所有 3 种方法相同的效果,其中最后一种方法与此方法基本相同,但 computed_values 内联。
  • @MartijnPieters 啊,看来我当时误解了他的回答。谢谢你的澄清。
【解决方案3】:
new_list = []
for (x, y) in old_list:
  new_x = func(x)
  if new_x: new_list.append((new_x, y))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-12
    • 2015-07-21
    相关资源
    最近更新 更多