11

next()withを使用して 1 レベル深くループしたいos.walk

私のコードの重要な行:

for root, dirs, files in os.walk(dir).next(1): 

エラー:

AttributeError: 'generator' オブジェクトに属性 'next' がありません

コミュニティで提案されているよう.next(x)に、古いものを置き換えるために使用しようとしましたが、これも機能しません。next()[1]

4

2 に答える 2

23

あなたはpython3を使用しています。python3 では、next()メソッドは に置き換えられました__next__。これらのメソッドは引数を受け入れませa.__next__(1)(つまり、エラーです)。イテレータを1 つ進めます。より多くの要素でそれを進めるには、next繰り返し呼び出します。

イテレータを 1 回使用して進めたい場合は、next組み込み関数を使用することをお勧めします。

>>> L = (x for x in range(10))
>>> next(L)
0
>>> next(L)
1

注:next組み込み関数は python2.6 で追加されたと思いますので、python2 でも安全に使用できます。

ただし、コードでは、呼び出しはまったく意味がありませんnext。それを使って何を達成しようとしていますか?

やっている:

for root, dirs, files in next(os.walk(dir)):

は、文字列のリストを含む 3 つの要素のタプルであるnextの最初の要素を返すため、エラーが発生します。os.walkしかし、ループはタプルforを繰り返し処理し、単一のリストを に展開しようとします。いずれかのディレクトリに含まれるファイル/サブディレクトリが 3 つより多いか少ない場合、コードは失敗します。root, dirs, files

最初のディレクトリのみをスキップする場合nextは、個別に呼び出す必要があります。

iterable = os.walk(directory)
next(iterable)   # throw away first iteration
for root, dirs, files in iterable:
   #...

Martijn が推測したように、ディレクトリのみを反復処理する場合は、特に何もする必要はありません。rootループ内でandfiles変数を使用しないでください。この場合、それらの名前を に変更することをお勧めします。これは、割り当てが必要_な変数を示すためによく使用されますが、まったく使用されません。

for _, dirs, _ in os.walk(directory):
    # Work only on "dirs". Don't care for "_"s

niterableの最初の要素を消費したい場合itertools.isliceは、 andcollections.dequeを使用して、メモリを消費せずに高速に実行できます。

from itertools import islice
from collections import deque

def drop_n_elements(n, iterable):
    deque(islice(iterable, n), maxlen=0)

そして、次のように使用します。

iterable = os.walk(directory)
drop_n_elements(N, iterable) # throw away first N iterations
for root, dirs, files in iterable:
    # ...

iterable の最初の n 個の要素を削除するさらに高速で簡単な方法があることに気付きました。

def drop_n_elements(n, iterable):
    next(islice(iterable, n, n), None)

のメソッドをdeque(..., maxlen=0)1 回呼び出すだけなので、 を使用するよりもわずかに高速です。nextislice

于 2013-08-31T12:00:01.243 に答える