5
def flattenList(toFlatten):
 final=[]
 for el in toFlatten:
  if isinstance(el, list):
   final.extend(flattenList(el))
  else:
   final.append(el)
 return final

リストがどれだけ深くネストするかわからないときは、これが私がこれを行うために考えることができる唯一の方法です。

4

4 に答える 4

7
  1. Pythonでのタイプチェックは避けてください。この場合、これは、タイプで区別する任意にネストされた構造を回避することを意味します。特定の属性を調べるなど、タイプチェック以外方法でトラバースできる独自のノードタイプを作成できます。

  2. 1レベルまたは正確にnレベルを平坦化するには、を参照してitertools.chain.from_iterableください。

  3. 「機能的」とはどういう意味かわかりません。このコードはかなり機能的です。再帰を使用し(クレジットではありません!)、引数を変更しません。(厳密に言えば、リストを作成するために可変状態を使用しますが、それはPythonで行う方法です。

  4. もう1つの機能属性は、遅延評価だと思います。このようにこれを実装することができます

    def flatten(toFlatten):
        for item in toFlatten:
            if isinstance(item, list): # Ewww, typchecking
                for subitem in flatten(item): # they are considering adding 
                    yield subitem             # "yield from" to the  language
                                              # to give this pattern syntax
            else:
                yield item
    
  5. Pythonでは再帰が非常に制限されており(少なくとも、そのすべての主要な実装では)、通常、任意の深さで再帰を回避する必要があります。これ(およびすべての再帰コード)を書き直して反復を使用することは非常に可能です。これにより、これがよりスケーラブルになります(そして、機能が低下します。これは、FPには特に適していないPythonでは良いことです)。

于 2010-03-18T16:55:49.903 に答える
3

reduceこの回答は、Pythonでこれを使用したくない理由を説明しています。

スニペットを検討してください

reduce(operator.add, [[1], [2], [3], [4], [5]])

これは何をする必要がありますか?

[1] + [2] => [1, 2]
[1, 2] + [3] => This makes a new list, having to go over 1, then 2, then 3. [1, 2, 3]
[1, 2, 3] + [4] => This has to copy the 1, 2, and 3 and then put 4 in the new list
[1, 2, 3, 4] + [5] => The length of stuff I have to copy gets bigger each time!

この2次動作は完全に回避できます。元のソリューション(および他の任意の数のソリューション)は、これらの中間コピーステップを形成しません。

于 2010-03-18T17:54:36.093 に答える
2

itertoolsのドキュメントの下に、flatten()関数があります

于 2010-03-18T17:11:14.467 に答える
1

別のオプションがあります(ただし、何かが反復可能であり、したがって「アトム」ではないかどうかをテストするなど、型チェックよりもクリーンなものがある場合があります)。

def flatten(lst):
    if not isinstance(lst,list):
        return [lst]
    else:
        return reduce(lambda x,y:x+y,[flatten(x) for x in lst],[])

それはスキームのようなものに基づいています。

于 2010-03-18T17:07:20.603 に答える