列表理解与昂贵的计算

时间:2017-09-19 10:05:27

标签: python list-comprehension

所以我有一些列表推导,如下所示。

li = [some_computation(x) for x in y if some_computation(x)]

我只想要与some_computation相关的真值。

  1. 这会计算some_computation(x)两倍,因为列表理解看起来如此吗?如果some_computation价格昂贵,我真的想要这个。 (我觉得这可能就是:(
  2. 有更好的方法吗?也许将其分解为常规for循环并仅在some_computation(x)时附加,但我喜欢理解。

3 个答案:

答案 0 :(得分:4)

some_computation将被计算两次,为避免这种情况,您可以使用filter来丢弃错误的结果:

li = list(filter(None, (some_computation(x) for x in y)))

或者像Jon Clements建议的那样使用嵌套的生成器表达式:

li = [el for el in (some_computation(x) for x in y) if el]

答案 1 :(得分:1)

  1. 是的,它会执行some_computation两次,试试这个并看到:

    def compute(x):
        print("Compute...")
        return 2*x
    y=[1,3,5]
    ls=[compute(x) for x in y if compute(x)]
    
  2. 输出:

    Compute...
    Compute...
    Compute...
    Compute...
    Compute...
    Compute...
    
    1. 更好的Python方式:

      ls=[x for x in [compute(z) for z in y] if x]

答案 2 :(得分:0)

  1. 这会计算some_computation(x)两次,因为列表理解看起来如此吗?
  2. 是。它计算两次。

    1. 有更好的方法吗?也许是将它分解为常规for循环并附加,如果只是some_computation(x),但我喜欢理解。
    2. 你必须定期循环。发电机在运行中而不是存储。可能你可以采用算法来选择x out并进行计算

      li = [computation(x) for x in y if choose(x)]
      

      或者你必须在if条件下进行迭代,这相当于调用计算两次。