SICP-1.6-高阶函数

高阶函数

  • 将函数作为参数
  • 例如
    • 1 def sum_naturals(n):
      2         total, k = 0, 1
      3         while k <= n:
      4             total, k = total + k, k + 1
      5         return total
      def sum_cubes(n):
              total, k = 0, 1
              while k <= n:
                  total, k = total + k*k*k, k + 1
              return total
      def pi_sum(n):
              total, k = 0, 1
              while k <= n:
                  total, k = total + 8 / ((4*k-3) * (4*k-1)), k + 1
              return total
    • 以上三个例子中有许多共同的部分
      • def <name>(n):
            total, k = 0, 1
            while k <= n:
                total, k = total + <term>(k), k + 1
            return total
    • 高阶函数形式
    • def summation(n, term):
          total, k = 0, 1
          while k <= n:
              total, k = total + term(k), k + 1
          return total
      
      def cube(x):
          return x*x*x
      
      def sum_cubes(x):
          return summation(x,cube)
    • 函数环境
    • 黄金比例
    • def improve(update, close, guess=1):
              while not close(guess):
                  guess = update(guess)
              return guess
      
      def golden_update(guess):
              return 1/guess + 1
      
      def square_close_to_successor(guess):
              return approx_eq(guess * guess, guess + 1)
      
      def approx_eq(x, y, tolerance=1e-15):
              return abs(x - y) < tolerance
      
      improve(golden_update, square_close_to_successor)
  • 高阶函数的不足
    • 在全局环境中名称复杂
    • 每一个函数的形参个数是由限制的

函数的嵌套定义

  • 解决高阶函数存在的不足
  • def sqrt(a):
            def sqrt_update(x):
                return average(x, a/x)
            def sqrt_close(x):
                return approx_eq(x * x, a)
            return improve(sqrt_update, sqrt_close)
  • 嵌套定义中的函数作用域
    • 每一个嵌套的函数在定义函数内环境
    • #不是函数的调用处
  • 函数作用域的实现方法
    • 每一个函数都有他的父环境
    • 当函数被调用时,在其父环境中评估
  • 函数作用域的好处
    • 局部环境中的绑定不会影响全局环境
  • def square(x):
        return x * x
    
    def successor(x):
        return x + 1
    
    def compose1(f,g):
        def h(x):
            return f(g(x))
        return h
    
    square_successor = compose1(square,successor)
    result = square_successor(12)

     

牛顿法

  • def newton_update(f, df):
            def update(x):
                return x - f(x) / df(x)
            return update
    
    def find_zero(f, df):
            def near_zero(x):
                return approx_eq(f(x), 0)
            return improve(newton_update(f, df), near_zero)
    
    def square_root_newton(a):
            def f(x):
                return x * x - a
            def df(x):
                return 2 * x
            return find_zero(f, df)

     

Currying

  • >>> def curried_pow(x):
            def h(y):
                return pow(x, y)
            return h
    >>> curried_pow(2)(3)
    8
    def curry2(f):
            """Return a curried version of the given two-argument function."""
            def g(x):
                def h(y):
                    return f(x, y)
                return h
            return g
    def uncurry2(g):
            """Return a two-argument version of the given curried function."""
            def f(x, y):
                return g(x)(y)
            return f

     

  • 环境图

匿名函数

  • 可以看做
    •        lambda            x            :          f(g(x))
      "A function that    takes x    and returns     f(g(x))"

函数装饰器

  • >>> def trace(fn):
            def wrapped(x):
                print('-> ', fn, '(', x, ')')
                return fn(x)
            return wrapped
    >>> @trace
        def triple(x):
            return 3 * x
    >>> triple(12)
    ->  <function triple at 0x102a39848> ( 12 )
    36
    • @trace等同于
    • >>> def triple(x):
              return 3 * x
      >>> triple = trace(triple)
posted @ 2017-06-20 17:49  elieyes  阅读(662)  评论(4编辑  收藏  举报