【问题标题】:Passing function objects and using them in other functions in Python 3.8.4在 Python 3.8.4 中传递函数对象并在其他函数中使用它们
【发布时间】:2020-07-14 17:18:26
【问题描述】:

我在看这个问题:

cons(a, b) 构造一个对,car(pair)cdr(pair) 返回该对的第一个和最后一个元素。例如,car(cons(3, 4)) 返回 3,cdr(cons(3, 4)) 返回 4。

鉴于这种缺点的实现:

def cons(a, b):
    def pair(f):
        return f(a,b)
    return pair

实现 car 和 cdr。

我认出了 lambda 表达式,但我仍然不确定它是如何工作的。答案如下:

def car(f):
    z = lambda x, y: x
    return f(z)

def cdr(f):
    z = lambda x, y: y
    return f(z)

如果 f 是函数对象,是不是将 z 传递给 f 调用 lambda f : f(a,b),其中 z 有 2 个参数,而另一个 lambda 只有 1 个参数?

这个解决方案是如何工作的?

【问题讨论】:

    标签: python lambda function-object


    【解决方案1】:

    您必须了解一对是如何表示的。一对由三个事物组成:第一个元素、第二个元素和一个函数。最重要的是,这两个元素不能“直接”访问(尽管见下文):您可以通过该对的第三个成员访问它们。该函数采用 另一个 函数,并返回将该函数应用于两个“隐藏”元素的结果。

    car 采用 pair 函数并将其应用于返回其两个参数中的第一个的函数。

    cdr 采用 pair 函数并将其应用于返回其两个参数中的第二个的函数。

    您可以按如下方式进行跟踪,如果您重写 cons = lambda a, b: lambda f: f(a, b) 会更容易:

    car(cons(3, 5)) == cons(3, 5)(lambda x, y: x)
                    == (lambda a, b: lambda f: f(a, b))(3, 5)(lambda x, y: x)
                    == (lambda f: f(3, 5))(lambda x, y: x)
                    == (lambda x, y: x)(3, 5)
                    == 3
    
    
    cdr(cons(3, 5)) == cons(3, 5)(lambda x, y: y)
                    == (lambda a, b: lambda f: f(a, b))(3, 5)(lambda x, y: y)
                    == (lambda f: f(3, 5))(lambda x, y: y)
                    == (lambda x, y: y)(3, 5)
                    == 5
    

    cons(3, 5) 实质上将值 3 和 5 存储在它创建的 pair 函数的 __closure__ 属性中。

    >>> p1 = cons(3, 5)
    >>> p1.__closure__[0].cell_contents
    3
    >>> p1.__closure__[1].cell_contents
    5
    

    【讨论】:

      【解决方案2】:

      让我们评估car(cons(3, 4))

      cons(3, 4)

      a = 3
      b = 4
      def pair(f):
          return f(3, 4)
      return pair
      

      所以现在我们有car(pair),其中pair 是:

      def pair(f):
          return f(3, 4)
      

      car(pair)

      让我们看看car会发生什么:

      f = pair
      z = lambda x, y: x
      return f(z)
      

      所以最后一条语句实际上可以读作:

      return pair(z)
      

      return pair(lambda x, y: y)
      

      为简单起见,让我们将 z 重写为常规函数:

      def z(x, y):
          return x
      

      return pair(z)

      现在我们以z 作为参数运行pair

      记住,pair 定义为:

      def f(n):
          return n(3, 4)
      

      所以 n = z,我们应该返回:

      z(3, 4)
      

      z 所做的实际上是“返回第一个参数”。

      还有……给你:)

      【讨论】:

        猜你喜欢
        • 2016-01-19
        • 2020-12-15
        • 2011-02-09
        • 1970-01-01
        • 2023-04-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多