Avoid computing the same expression twice in list comprehension [duplicate]

我的未来我决定 提交于 2020-01-06 03:40:06

问题


I am using a function in a list comprehension and an if function:

new_list = [f(x) for x in old_list if f(x) !=0]

It annoys me that the expression f(x) is computed twice in each loop.

Is there a way to do it in a cleaner way? Something along the lines of storing the value or including the if statement at the beginning of the list comprehension.


回答1:


Compute the results beforehand and iterate over them

new_list = [x for x in map(f, old_list) if x !=0]

Moreover, since map computes the result per element when the element is accessed this is just one loop.




回答2:


you could use a generator expression (in order to avoid creating an unnecessary list) inside your list comprehension:

new_list = [fx for fx in (f(x) for x in old_list) if fx != 0]

starting from python 3.8 you will be able to do this:

new_list = [fx for x in old_list if (fx := f(x)) != 0]



回答3:


in Python 3.8 we'll have the "walrus operator" and be able to do just that!

[y for x in old_list if (y := f(x)) != 0]



回答4:


You could use a filter to remove results:

def f (x):
  return x * 2

old_list = [0, 1, 2, 3]

new_list = filter(lambda x: x != 0, [f(x) for x in old_list])

for x in new_list:
  print(x)

See it working here.

Alternatively you could memoize the function so as to prevent ever having to compute the same result twice:

def f (x):
  return x * 2

def memoize(f):
    memo = {}
    def helper(x):
        if x not in memo:
            print("Computing result for %s" % x)        
            memo[x] = f(x)
        return memo[x]
    return helper

memF = memoize(f)

old_list = [0, 1, 2, 3]

new_list = [memF(x) for x in old_list if memF(x) != 0]

for x in new_list:
  print(x)

Which is available here.



来源:https://stackoverflow.com/questions/56967363/avoid-computing-the-same-expression-twice-in-list-comprehension

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!