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

时间:2022-01-21 18:27:15

When programming in python, I now avoid map, lambda and filter by using list comprehensions because it is easier to read and faster in execution. But can reduce be replaced as well?

在python中编程时,我现在通过使用列表推导来避免map,lambda和filter,因为它更易于阅读并且执行速度更快。但是还可以减少更换吗?

E.g. an object has an operator union() that works on another object, a1.union(a2), and gives a 3rd object of same type.

例如。一个对象有一个运算符union(),它对另一个对象a1.union(a2)起作用,并给出一个相同类型的第三个对象。

I have a list of objects:

我有一个对象列表:

L = [a1, a2, a3, ...]

How to have the union() of all these objects with list comprehensions, the equivalent of:

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

result = reduce(lambda a, b :a.union(b), L[1:], L[0])

4 个解决方案

#1


17  

It is no secret that reduce is not among the favored functions of the Pythonistas.

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

Generically, reduce is a left fold on a list

通常,reduce是列表中的左侧折叠

It is conceptually easy to write a fold in Python that will fold left or right on a iterable:

从概念上讲,在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

Without some atrocious hack, this cannot be replicated in a comprehension because there is not accumulator type function in a comprehension.

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

Just use reduce -- or write one that makes more sense to you.

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

#2


3  

Not really. List comprehensions are more similar to map, and possibly filter.

并不是的。列表推导更类似于map,并且可能过滤。

#3


3  

Since a list comprehension definitionally generates another list, you can't use it to generate a single value. The aren't for that. (Well... there is this nasty trick that uses a leaked implementation detail in old versions of python that can do it. I'm not even going to copy the example code here. Don't do this.)

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

If you're worried about the stylistic aspects of reduce() and its ilk, don't be. Name your reductions and you'll be fine. So while:

如果您担心reduce()及其类似的风格方面,请不要这样做。命名你的减少,你会没事的。所以同时:

all_union = reduce(lambda a, b: a.union(b), L[1:], L[0])

isn't great, this:

不是很好,这个:

def full_union(input):
    """ Compute the union of a list of sets """

    return reduce(lambda a, b: a.union(b), input[1:], input[0])

result = full_union(L)

is pretty clear.

非常清楚。

If you're worried about speed, check out the toolz and cytoolz packages, which are 'fast' and 'insanely fast,' respectively. On large datasets, they'll often let you avoid processing your data more than once or loading the whole set in memory at once, in contrast to list comprehensions.

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

#4


2  

A common use of reduce is to flatten a list of lists. You can use a list comprehension instead.

reduce的常见用法是压缩列表列表。您可以使用列表推导。

L = [[1, 2, 3], [2, 3, 4], [3, 4, 5]]

with reduce

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]

with list comp

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

print(flattened)

[1, 2, 3, 2, 3, 4, 3, 4, 5]

If your problem can be solved by operating on the flattened list, this is an effective replacement. Contrast these one-liners for the given example:

如果通过在展平列表上操作可以解决您的问题,这是一个有效的替代品。对比给定示例的这些单行:

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}

#1


17  

It is no secret that reduce is not among the favored functions of the Pythonistas.

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

Generically, reduce is a left fold on a list

通常,reduce是列表中的左侧折叠

It is conceptually easy to write a fold in Python that will fold left or right on a iterable:

从概念上讲,在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

Without some atrocious hack, this cannot be replicated in a comprehension because there is not accumulator type function in a comprehension.

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

Just use reduce -- or write one that makes more sense to you.

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

#2


3  

Not really. List comprehensions are more similar to map, and possibly filter.

并不是的。列表推导更类似于map,并且可能过滤。

#3


3  

Since a list comprehension definitionally generates another list, you can't use it to generate a single value. The aren't for that. (Well... there is this nasty trick that uses a leaked implementation detail in old versions of python that can do it. I'm not even going to copy the example code here. Don't do this.)

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

If you're worried about the stylistic aspects of reduce() and its ilk, don't be. Name your reductions and you'll be fine. So while:

如果您担心reduce()及其类似的风格方面,请不要这样做。命名你的减少,你会没事的。所以同时:

all_union = reduce(lambda a, b: a.union(b), L[1:], L[0])

isn't great, this:

不是很好,这个:

def full_union(input):
    """ Compute the union of a list of sets """

    return reduce(lambda a, b: a.union(b), input[1:], input[0])

result = full_union(L)

is pretty clear.

非常清楚。

If you're worried about speed, check out the toolz and cytoolz packages, which are 'fast' and 'insanely fast,' respectively. On large datasets, they'll often let you avoid processing your data more than once or loading the whole set in memory at once, in contrast to list comprehensions.

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

#4


2  

A common use of reduce is to flatten a list of lists. You can use a list comprehension instead.

reduce的常见用法是压缩列表列表。您可以使用列表推导。

L = [[1, 2, 3], [2, 3, 4], [3, 4, 5]]

with reduce

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]

with list comp

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

print(flattened)

[1, 2, 3, 2, 3, 4, 3, 4, 5]

If your problem can be solved by operating on the flattened list, this is an effective replacement. Contrast these one-liners for the given example:

如果通过在展平列表上操作可以解决您的问题,这是一个有效的替代品。对比给定示例的这些单行:

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}