【问题标题】:How does this reduce + lambda list filter function work?这个 reduce + lambda 列表过滤功能如何工作?
【发布时间】:2017-01-18 21:17:23
【问题描述】:

我看到下面的代码将一个列表过滤成两个类:

reduce(lambda(a,b),c: (a+[c],b) if c > 60 else (a,b + [c]), [49, 58, 76, 82, 88, 90],([],[]))

它是如何工作的? ([], []) 看起来在 lambda 中初始化 (a, b),但它是如何一步一步工作的呢?

这似乎也不适用于 Python 3。这是为什么呢?

【问题讨论】:

    标签: python lambda reduce


    【解决方案1】:

    它是如何工作的? ([], []) 看起来在 lambda 中初始化 (a, b),但它是如何一步一步工作的呢?

    在每一点,reduce 都会看到一个左侧操作数 (a, b),它是一对列表(最初是两个空列表)和一个元素 c。它将列表[c] 添加到ab,具体取决于它是否大于60,并返回新的列表对。因此,它最终会分别返回大于 60 和小于 60 的元素对。

    这似乎也不适用于 Python 3。这是为什么呢?

    在 Python3 中,您不能再定义一个显式采用元组的函数 - tuple unpacking has been removed。所以

    def foo((a, b)):
        ...
    

    在 Python3 中是非法的。这也是这里的问题(除了 lambda 形式)。

    【讨论】:

    • Python3: reduce(lambda a,c: (a[0]+[c],a[1]) if c > 60 else (a[0],a[1]+[c]), [49, 58, 76, 82, 88, 90],([],[]))
    【解决方案2】:

    要回答您的第一个查询,等效于使用 for 循环:

    >>> c = [49, 58, 76, 82, 88, 90]
    >>> final = ([], [])
    >>> for val in c:
    ...     if val > 60:
    ...             final[0].append(val)
    ...     else:
    ...             final[1].append(val)
    ... 
    >>> final
    ([76, 82, 88, 90], [49, 58])
    

    在python3中等价的是:

    In [8]: import functools
    
    In [9]: functools.reduce(lambda x,c: (x[0]+[c],x[1]) if c > 60 else (x[0],x[1] + [c]), [49, 58, 76, 82, 88, 90],([],[]))
    Out[9]: ([76, 82, 88, 90], [49, 58])
    

    【讨论】:

      【解决方案3】:

      看看下面的实验:

      >>> reduce(lambda(a,b),c: (a+[c],b) if c > 60 else (a,b + [c]), [49],([],[]))
      ([], [49])
      >>> reduce(lambda(a,b),c: (a+[c],b) if c > 60 else (a,b + [c]), [49,58],([],[]))
      ([], [49, 58])
      >>> reduce(lambda(a,b),c: (a+[c],b) if c > 60 else (a,b + [c]), [49,58,76],([],[]))
      ([76], [49, 58])
      >>> reduce(lambda(a,b),c: (a+[c],b) if c > 60 else (a,b + [c]), [49,58,76,82],([],[]))
      ([76, 82], [49, 58])
      >>> reduce(lambda(a,b),c: (a+[c],b) if c > 60 else (a,b + [c]), [49,58,76,82,88,90],([],[]))
      ([76, 82, 88, 90], [49, 58])
      

      函数reduce描述如下:

      reduce(...)
          reduce(function, sequence[, initial]) -> value
      
          Apply a function of two arguments cumulatively to the items of a sequence,
          from left to right, so as to reduce the sequence to a single value.
      

      在我们的示例中,function 是一个 lambda 函数,第一个参数是一个二元素元组 (a,b),第二个参数是一个整数 c,从列表中挑选出来进行处理。由于函数产生一个 2 元素的列表元组,它被初始化为 ([], [])。处理开始时,如果元素>60,则将其添加到元组的第一个列表中;否则它被添加到元组的第二个列表中。

      a+[c] 的语法实际上是列表的extend 语法。我们不能做a+c,因为a 是一个列表,而c 是一个整数。同样,对于b+[c]

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-07-12
        • 1970-01-01
        • 2018-01-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-01-11
        • 1970-01-01
        相关资源
        最近更新 更多