web-dev-qa-db-ja.com

Pythonにリストの「フラット化」機能がないのはなぜですか?

ErlangとRuby=の両方に、配列をフラット化するための関数が付属しています。言語に追加するための、とてもシンプルで便利なツールのようです。これを行うことができます:

>>> mess = [[1, [2]], 3, [[[4, 5]], 6]]
>>> mess.flatten()
[1, 2, 3, 4, 5, 6]

あるいは:

>>> import itertools
>>> mess = [[1, [2]], 3, [[[4, 5]], 6]]
>>> list(itertools.flatten(mess))
[1, 2, 3, 4, 5, 6]

代わりに、Pythonでは、配列を最初からフラット化する関数を作成するという問題を経験する必要があります。これはばかげているように思えますが、配列のフラット化はよくあることです。 2つの配列を連結するためのカスタム関数を作成する必要があるようなものです。

私はこれを無益にグーグル化したので、私はここで尋ねています。 Python 3のような成熟した言語には10万個のさまざまなバッテリーが付属していて、配列をフラット化する簡単な方法が提供されない)特別な理由はありますか?そのような機能が議論され、ある時点で拒否されましたか?

40
Hubro

標準ライブラリに追加されるflatten関数の提案は、時々 python-dev および python-ideas メーリングリストに表示されます。 Python開発者は通常、次の点で応答します:

  1. 1レベルのフラット化(イテラブルのイテラブルを単一のイテラブルに変換する)は、簡単な1行式_(x for y in z for x in y)_であり、いずれの場合も、標準ライブラリに _itertools.chain.from_iterable_という名前で既に存在します。

  2. 汎用マルチレベルフラットニングの使用例は何ですか?これらは、関数を標準ライブラリに追加するのに十分魅力的ですか?

  3. 汎用マルチレベルフラット化は、フラット化するタイミングと放置するタイミングをどのように決定するのでしょうか。 「反復可能なインターフェースをサポートするものをすべて平坦化する」のようなルールは機能すると思いますが、それはflatten('a')の無限ループにつながります。

例を参照してください Raymond Hettinger

Comp.lang.pythonでad nauseamについて議論されました。人々は、平凡なソリューションをまだ持っていない正当なユースケースを見つけるよりも、独自のバージョンのflattenを書くことを楽しんでいるようです。

汎用フラットナは、何がアトミックで、何がさらに細分化できるかを通知するために何らかの方法が必要です。また、ノードだけでなくリーフにもデータのあるツリー状のデータ構造を持つ入力をカバーするためにアルゴリズムをどのように拡張する必要があるかは明らかではありません(前順、後順、順トラバーサルなど)。

37
Gareth Rees

そのようなメソッドは付属していますが、フラット化とは呼ばれていません。 " chain "と呼ばれます。イテレータを返すので、リストに戻すにはlist()関数を使用する必要があります。 *を使用したくない場合は、2番目の「from_iterator」バージョンを使用できます。これは same in Python 3.で機能します。3。リスト入力がリストのリストでない場合は失敗します。

[[1], [2, 3], [3, 4, 5]] #yes
[1, 2, [5, 6]] #no

かつて、compiler.astモジュールに flatten メソッドがありましたが、これは2.6で非推奨となり、3.0で削除されました。任意にネストされたリストに必要な任意の深度再帰は、Pythonの保守的な最大再帰深度ではうまく機能しません。コンパイラが削除された理由は、主に mess でした。コンパイラは ast に変換されましたが、flattenが残されました。

Numpyの配列とそのライブラリのフラット化により、任意の深さを実現できます。

8
World Engineer