web-dev-qa-db-ja.com

python:マップ、ラムダ、フィルターなどのリスト内包表記に変換できますか?

Pythonでプログラミングするときは、リスト内包表記を使用してmaplambdaおよびfilterを回避しました。読みやすく、実行速度が速いためです。しかし、reduceも置き換えることができますか?

例えば。オブジェクトには、別のオブジェクトunion()で機能する演算子a1.union(a2)があり、同じタイプの3番目のオブジェクトを返します。

オブジェクトのリストがあります:

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

これらのすべてのオブジェクトのunion()にリスト内包表記を含める方法。

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

それがPythonistaの 支持された関数の中にない であることは秘密ではありません。

一般的に、 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

ひどいハックがなければ、内包にはアキュムレータタイプの関数がないため、これを内包で複製することはできません。

単にreduceを使用するか、よりわかりやすいものを記述してください。

18
dawg

リスト内包表記は定義上別のリストを生成するため、これを使用して単一の値を生成することはできません。それはforではありません。 (まあ... この厄介なトリック があります=pythonの古いバージョンでリークされた実装の詳細を使用できます。コピーするつもりはありませんここにサンプルコードがあります。これを行わないでください。)

reduce()のスタイルとその同類について心配している場合は、心配しないでください。削減に名前を付ければ、大丈夫です。その間:

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

これは素晴らしいことではありません、これ:

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)

かなり明確です。

速度が心配な場合は、toolz および cytoolz パッケージを確認してください。それぞれ「速い」と「めちゃくちゃ速い」。大規模なデータセットでは、リスト内包とは対照的に、データを複数回処理したり、セット全体を一度にメモリに読み込んだりすることが避けられます。

5
Nate

あんまり。リスト内包表記はmapに似ており、場合によってはfilterに似ています。

4
bigblind

Reduceの一般的な使用法は、リストのリストをフラット化することです。代わりにリスト内包表記を使用できます。

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

削減あり

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]

リストコンプ付き

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

print(flattened)

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

フラット化されたリストを操作して問題を解決できる場合、これは効果的な置き換えです。与えられた例のこれらの1行を比較してください。

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}
2
Nicholas Morley