python:可以减少被翻译成map,lambda和filter这样的列表推导吗?

Eri*_* H. 24 python reduce list map-function

当在Python编程,我现在避免map,lambdafilter通过使用列表理解,因为它是在执行中更容易阅读和更快.但也reduce可以替换?

例如,对象具有union()在另一个对象上工作的运算符a1.union(a2),并且给出相同类型的第三个对象.

我有一个对象列表:

L = [a1, a2, a3, ...]
Run Code Online (Sandbox Code Playgroud)

如何将所有这些对象的union()与列表推导相对应,相当于:

result = reduce(lambda a, b :a.union(b), L[1:], L[0])
Run Code Online (Sandbox Code Playgroud)

daw*_*awg 18

众所周知,reduce 不是 Pythonistas 最喜欢的功能之一.

通常,reduce列表中左侧折叠

在Python中编写折叠在概念上很容易在迭代上向左或向右折叠:

def fold(func, iterable, initial=None, reverse=False):
    x=initial
    if reverse:
        iterable=reversed(iterable)
    for e in iterable:
        x=func(x,e) if x is not None else e
    return x
Run Code Online (Sandbox Code Playgroud)

没有一些残暴的黑客,这不能在理解中复制,因为在理解中没有累加器类型函数.

只需使用reduce - 或者写一个对你更有意义的东西.


Nat*_*ate 6

由于列表推导式定义生成另一个列表,因此您不能使用它来生成单个值。不是为了那个。(嗯……有一个讨厌的技巧,它在旧版本的 python 中使用泄露的实现细节可以做到这一点。我什至不打算在这里复制示例代码。不要这样做。)

如果您担心其风格方面的问题reduce(),请不要担心。说出你的减少,你会没事的。所以同时:

all_union = reduce(lambda a, b: a.union(b), L[1:], L[0])
Run Code Online (Sandbox Code Playgroud)

不是很好,这个:

from functools import reduce

def full_union(input):
    """ Compute the union of a list of sets """
    return reduce(set.union, input[1:], input[0])

result = full_union(L)
Run Code Online (Sandbox Code Playgroud)

很清楚。

如果您担心速度,请查看toolzcytoolz包,它们分别是“快速”和“非常快”。在大型数据集上,与列表推导式相比,它们通常会让您避免多次处理数据或一次将整个数据集加载到内存中。

  • 为了使 `reduce()` 表达式本身可读,请使第一个参数不是 lambda。例如: `reduce(set.union, <list of set>)` 有时这需要你在调用 `reduce` 之外的某个地方定义(并因此命名)操作符。 (2认同)

Nic*_*ley 5

reduce 的一个常见用途是展平列表列表。您可以改用列表理解。

L = [[1, 2, 3], [2, 3, 4], [3, 4, 5]]
Run Code Online (Sandbox Code Playgroud)

与减少

from functools import reduce  # python 3
flattened = reduce(lambda x, y: x + y, L)

print(flattened)

[1, 2, 3, 2, 3, 4, 3, 4, 5]
Run Code Online (Sandbox Code Playgroud)

与列表比较

flattened = [item for sublist in L for item in sublist]

print(flattened)

[1, 2, 3, 2, 3, 4, 3, 4, 5]
Run Code Online (Sandbox Code Playgroud)

如果您的问题可以通过对扁平列表进行操作来解决,那么这是一个有效的替代方案。对比给定示例中的这些单行:

all_union = reduce(lambda a, b: set(a).union(set(b)), L)

{1, 2, 3, 4, 5}

all_union = set([item for sublist in L for item in sublist])

{1, 2, 3, 4, 5}
Run Code Online (Sandbox Code Playgroud)

  • 使用“sum(L, [])”。也就是说,sum/list 理解会创建一个“全长”列表,而“reduce(operator.or_, map(set, L), set())”则不会。 (3认同)

big*_*ind 4

并不真地。map列表推导式与and更相似filter