Pythonでプログラミングするときは、リスト内包表記を使用してmap
、lambda
およびfilter
を回避しました。読みやすく、実行速度が速いためです。しかし、reduce
も置き換えることができますか?
例えば。オブジェクトには、別のオブジェクトunion()
で機能する演算子a1.union(a2)
があり、同じタイプの3番目のオブジェクトを返します。
オブジェクトのリストがあります:
L = [a1, a2, a3, ...]
これらのすべてのオブジェクトのunion()にリスト内包表記を含める方法。
result = reduce(lambda a, b :a.union(b), L[1:], L[0])
それがPythonistaの 支持された関数の中にない であることは秘密ではありません。
概念的には、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を使用するか、よりわかりやすいものを記述してください。
リスト内包表記は定義上別のリストを生成するため、これを使用して単一の値を生成することはできません。それは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 パッケージを確認してください。それぞれ「速い」と「めちゃくちゃ速い」。大規模なデータセットでは、リスト内包とは対照的に、データを複数回処理したり、セット全体を一度にメモリに読み込んだりすることが避けられます。
あんまり。リスト内包表記はmap
に似ており、場合によってはfilter
に似ています。
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}