0

たとえば、次のようなネストされたリストがあります。

 test = [[15, [7, [None], [11, [None], [13, [None], [None]]]], [None]], [20, [None], [None]]] 

これから、ネストに含まれる整数のみを使用して別のリストを作成したかったのです。これはこれを返します:

[15, 7, 11, 13, 20]

私はこの再帰関数を作成して、達成する必要があることを実行しましたが、これが最善の方法ではないと思わずにはいられませんでした。それを行うためのよりPythonicまたは効率的な方法はありますか?

def nest_search(nest, hold=[]):
    for item in nest:
        if isinstance(item, int):
            hold.append(item)
        if isinstance(item, list):
            nest_search(item, hold)
    return hold

>>> print nest_search(test)
[15, 7, 11, 13, 20]
4

2 に答える 2

2

私が見る唯一のunpythonicは、デフォルトの引数です。それが期待どおりに機能しない理由については、この質問を参照してください。

これが私がそれを修正する方法です:

def nest_search(nest, hold=None):
    if hold is None:
        hold = []
    for item in nest:
        if isinstance(item, int):
            hold.append(item)
        if isinstance(item, list):
            nest_search(item, hold)
    return hold

別の実装では、関数をジェネレーターにして、最後に返されるリストに値を追加するのではなく、値を1つずつ生成します。(リストが必要な場合は、ジェネレーター呼び出しをlistコンストラクターでラップするだけです)。

def nest_search_gen(nest):
    for item in nest:
        if isinstance(item, int):
            yield item
        if isinstance(item, list):
            yield from nest_search_gen(item)

yield fromこれは、 Python3.3で導入された新しい構文を使用します。以前のバージョンを使用している場合は、最後の行を次のように置き換えることで同じ効果を得ることができます。

for i in nest_search_gen(item):
    yield i
于 2012-11-23T03:54:45.390 に答える
1

ここflattenに掲載されている解決策を使用して、次のようなものを試すことができます。

>>> def flatten(x):
    try:
      it = iter(x)
    except TypeError:
      yield x
    else:
      for i in it:
        for j in flatten(i):
          yield j
>>> filter(bool, flatten(test))
[15, 7, 11, 13, 20]

2つの別々の機能flattenを使用するfilter方が明確だと思います。モジュール性を促進して、一方を他方なしで使用できるようにします。

于 2012-11-23T03:58:14.290 に答える