C# や Ruby では些細でエレガントな、オブジェクトの配列に対する単純なクエリを Python で作成しようとしていますが、Python でそれをエレガントにするのに苦労しています。私は何か間違ったことをしていると思います。
C# の場合:
list.Where(x => x.Foo > 10).Select(x => x.Bar).Where(x => x.Baz.StartsWith("/"))
list[0].Bar
これにより、リスト内の他のすべてのアイテムについて、list[0].Foo
10 を超えて でlist[0].Bar.Baz
始まるなどの列挙が作成されます。'/'
データは左から右に明確に流れ、右側にさらにフィルタリング/射影/集計を追加できます。
ルビーの場合:
list.select { |x| x.foo > 10 }.map(&:bar).select { |x| x.baz.starts_with? '/' }
繰り返しますが、これは左から右へのかなり明確なフローであり、さらに操作を簡単に追加できます。
しかし、私のPythonでの試みは裏返しで、裏返しで、一般的に醜いようです:
[x for x in (x.bar for x in (x for x in list if x.foo > 10)) if x.baz.startswith('/')]
これで、リスト内包表記を使用してマップとフィルターを 1 つのステップで組み合わせることができ、上記を次のように書き直すことができることがわかりました。
[x.bar for x in list if x.foo > 10 and x.bar.baz.startswith('/')]
しかし、それはむしろ要点を逃しています。1 つには、射影 x.bar はコストがかかる可能性があるため、2 回評価したくありません。別の例では、射影とフィルタリングは、ストリームに適用する可能性のある操作の 2 つにすぎません。並べ替え、集計、ページ分割などを行うことができます。すべての射影とフィルタが隣接している必要はなく、射影の前にフィルタを適用する必要もありません。後ではなく。
私はPythonをそうではないものにひねろうとしていますか? コマンドライン (シェル パイプ)、C#、Ruby、または Java (Python よりもはるかに面倒) のいずれであっても、私は通常、できる限りこのスタイルでプログラミングしようとします。痛いところを突くのはやめたほうがいいですか?