Python 2 では次のように記述できます:
In [5]: points = [ (1,2), (2,3)]
In [6]: min(points, key=lambda (x, y): (x*x + y*y))
Out[6]: (1, 2)
しかし、これは 3.x ではサポートされていません。
File "<stdin>", line 1
min(points, key=lambda (x, y): (x*x + y*y))
^
SyntaxError: invalid syntax
簡単な回避策は、渡されたタプルに明示的にインデックスを付けることです。
>>> min(points, key=lambda p: p[0]*p[0] + p[1]*p[1])
(1, 2)
これはとても醜い。ラムダが関数であれば、こうできる。
def some_name_to_think_of(p):
x, y = p
return x*x + y*y
しかし、 はlambda
単一の式しかサポートしていないため、 に部分を入れることはできませんx, y = p
。
この制限を回避するには他にどのような方法がありますか?
ベストアンサー1
いいえ、他に方法はありません。あなたはすべてをカバーしました。この問題を提起するのが最善の方法です。Python アイデア メーリング リストただし、ある程度の支持を得るためには、そこで大いに議論する覚悟が必要です。
実際のところ、「解決策がない」とは言いませんが、3 番目の方法としては、パラメータを展開するためだけにラムダ呼び出しをもう 1 レベル実装することですが、それは 2 つの提案よりも非効率的で読みにくくなります。
min(points, key=lambda p: (lambda x,y: (x*x + y*y))(*p))
Python 3.8 アップデート
Python 3.8 のリリース以降、PEP 572 (代入式) がツールとして利用できるようになりました。
したがって、ラムダ内で複数の式を実行するトリックを使用する場合 (通常はタプルを作成し、その最後のコンポーネントを返すことによってこれを行います)、次の操作を実行できます。
>>> a = lambda p:(x:=p[0], y:=p[1], x ** 2 + y ** 2)[-1]
>>> a((3,4))
25
この種のコードは、完全な関数よりも読みやすく実用的になることはめったにないことを念頭に置いておく必要があります。それでも、使用法はあります。この を操作するさまざまなワンライナーがある場合は、 を用意し、代入式を使用して、入力シーケンスを namedtuple に効果的に「キャスト」するpoint
価値がある可能性があります。namedtuple
>>> from collections import namedtuple
>>> point = namedtuple("point", "x y")
>>> b = lambda s: (p:=point(*s), p.x ** 2 + p.y ** 2)[-1]