【问题标题】:How can I avoid calling same function inside an inner pythonical style loop如何避免在内部 pythonical 样式循环中调用相同的函数
【发布时间】:2021-12-16 19:27:21
【问题描述】:

我有一个高 CPU 消耗功能,可以说:

def high_cost_function(p):
  ... lots of operations...
  return p

我想在python的内部循环下使用:

例子:

paths1= ['a','b','c']
paths2= ['b','c','d']
[any(x.startswith(high_cost_function(y)) for x in paths1) for y in paths2]

正确返回:[True, True, False]

但是,如您所见,我不得不为paths1 中的每个x 调用high_cost_function(y)

如果是正常循环,我可能会这样做:

for y in paths2:
  tmp_var = high_cost_function(y)
  for x in paths1:
    ...
    use tmp_var
    ...

有没有办法以第一种“pythonical 时尚方式”实现这一点??

【问题讨论】:

    标签: python python-3.x performance loops


    【解决方案1】:

    遍历(生成的)ys 列表,high_cost_function 已应用到该列表:

    [any(x.startswith(y) for x in paths1) for y in map(high_cost_function, paths2)]
    

    【讨论】:

    • 学究式地,map(high_cost_function, paths2) 在 Python 3 中不是一个列表:它是一个迭代器。
    • 因此在它前面有 "(generated)",因为这使得句子比“迭代迭代器”更容易理解,虽然它是正确的,但听起来令人困惑。
    【解决方案2】:

    answer by deceze 已经非常适合给定的用例。在更一般的情况下,当您可能还需要 y 本身时,您可以使用嵌套生成器表达式(在此处创建 dict 以说明同时使用两者):

    {y: any(x.startswith(hcf_y) for x in paths1)
     for (y, hcf_y) in ((y, high_cost_function(y)) for y in paths2)}
    

    或者使用第二个循环遍历单个元素列表来排序定义列表中的变量:

    {y: any(x.startswith(hcf_y) for x in paths1)
     for y in paths2 for hcf_y in [high_cost_function(y)]}
    

    【讨论】:

      【解决方案3】:

      如果high_cost_function的结果不大,也可以使用caching

      from functools import lru_cache
      @lru_cache(maxsize=None)
      def high_cost_function(p):
        ... lots of operations...
        return p
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-11-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-08
        相关资源
        最近更新 更多