【问题标题】:Python: define function only once [duplicate]Python:只定义一次函数[重复]
【发布时间】:2018-01-20 04:50:48
【问题描述】:

我想定义一个函数,例如多项式,来自预因子列表。类似的东西

order = [1,0,1]

def poly(x):
    res = 0
    for i, o in enumerate(order):
      res += o * x**i
    return res

所以poly(x) 返回1 + x²

我需要为不同的x 多次调用该函数,但前提条件相同。上面的函数每次调用都会执行for循环,效率相当低,尤其是order列表很长的时候。 如何只循环一次并为不同的x 调用结果? pythonic解决方案是什么?

【问题讨论】:

  • 你有我目前能想到的最有效的解决方案
  • 我会避免在每次迭代时提高功率,方法是保持先前的值,并在每次迭代时将其乘以 x。这也将消除对enumeratei 的需求。
  • 看看stackoverflow.com/questions/533382/…是否有帮助。
  • 如何只循环一次并为不同的 x 调用结果?什么是 pythonic 解决方案? - 甚至没有 数学 解决方案。也许您可以“隐藏”循环,但不能避免它。
  • NumPy 还有一个处理多项式求值的方法:docs.scipy.org/doc/numpy-1.12.0/reference/generated/…

标签: python


【解决方案1】:

Python 无法胜过数学。想到的唯一优化是避免计算乘以零的项:

def poly(x, order=(1, 0, 1)):
    res = 0
    for i, o in enumerate(order):
        if o:
            res += o * x**i
    return res

作为单行:

def poly2(x, order=(1, 0, 1)):
    return sum(o * x**i for i, o in enumerate(order) if o)

【讨论】:

    【解决方案2】:

    接受@Eugene Sh 的建议,可以消除重复的权力提升:

    xx = 1
    
    def poly(x, order):
        global xx
        xx = 1
        def f(x, o):
            global xx
            ret = xx * o
            xx *= x
            return ret
        return sum(f(x,o) for o in order)
    

    【讨论】:

      【解决方案3】:

      代码#1:求和循环(慢)

      def poly(x,order=[1,0,1]) : return sum([o*x**i for i,o in enumerate(order)])
      

      示例:

      poly(2,order=[2,0,2])

      >> 10
      >> Execution time: 5.29289245605e-05
      

      代码 #2: 求和图(更快)

      def poly(x,order=[1,0,1]) : return sum(map(lambda (i,o): o*x**i,enumerate(order)))
      

      示例:

      poly(2,order=[2,0,2])

      >> 10
      >> Execution time: 3.00407409668e-05
      

      【讨论】:

      • 它是如何回答问题的?
      • @EugeneSh。怎么不是?
      • 问题是我怎样才能只循环一次并为不同的x调用结果?
      • 据我所知,你无法避免循环,我使用地图混淆了,所以我回答了第二部分What is the pythonic solution?
      • 所以您评论的第一部分几乎就是问题的答案。其他一切都只是旁注。
      【解决方案4】:
      def make_poly(order):
          expression = ''
          for i, o in enumerate(order):
              if o:
                  if expression:
                      expression += ' + '
                  multiplier = '%d * ' % o if o > 1 else ''
                  if i == 0:
                      expression += str(o)
                  elif i == 1:
                      expression += multiplier + 'x'
                  else:
                      expression += multiplier + 'x**%d' % i
          loc = {}
          exec('def f(x):\n    return ' + expression, {}, loc)
          return loc['f']
      

      这会从传递的列表中创建一个表达式,删除所有为零的项和其他冗余操作。然后exec 用于创建一个返回的函数。

      >>> poly = make_poly([1, 0, 1])
      >>> poly(5)
      26
      

      【讨论】:

        猜你喜欢
        • 2019-10-21
        • 1970-01-01
        • 1970-01-01
        • 2021-07-20
        • 1970-01-01
        • 1970-01-01
        • 2012-10-21
        • 1970-01-01
        • 2011-02-26
        相关资源
        最近更新 更多