Error de atributo: siguiente ()

Quiero hacer un bucle de un nivel de profundidad usando next() con os.walk

Línea crítica de mi código:

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

Error:

AttributeError: el objeto ‘generador’ no tiene atributo ‘siguiente’

Intenté usar .next(x) para reemplazar el next()[1] como lo sugiere la comunidad, pero esto tampoco funciona.

Usted está utilizando python3. En python3, el método next() fue reemplazado por __next__ . Este método no acepta ningún argumento (es decir, a.__next__(1) es un error). Avanzan el iterador por uno . Para adelantarlo por más elementos llame al next repetidamente.

Si desea avanzar el iterador con un uso, sugeriría usar la next función incorporada:

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

Nota: la next función incorporada se agregó en python2.6, creo, por lo que es seguro de usar incluso en python2.

Sin embargo , en su código no tiene sentido llamar al next . ¿Qué estás tratando de lograr con eso?

Obra:

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

Se generará un error, ya que a next devuelve el primer elemento de os.walk , que es una tupla de tres elementos, que contiene listas de cadenas. Pero el bucle for repetirá sobre la tupla , intentando desempaquetar una sola lista en root, dirs, files . Si algún directorio tiene más o menos de 3 archivos / subdirectorios, el código fallará.

Si desea omitir solo el primer directorio, deberá llamar al next separado:

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

Si desea iterar solo en los directorios, como especula Martijn, entonces no tiene que hacer nada en particular. Simplemente no use las variables root y files en el bucle. En este caso, sugeriría cambiarles el nombre a _ , que a menudo se usa para indicar una variable que debemos asignar, pero no se usa en absoluto:

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

Si desea consumir los primeros n elementos de un iterable, puede usar itertools.islice y collections.deque para hacerlo rápido y sin consumo de memoria:

 from itertools import islice from collections import deque def drop_n_elements(n, iterable): deque(islice(iterable, n), maxlen=0) 

Y luego usarlo como:

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

Se me acaba de ocurrir que hay una forma aún más rápida y sencilla de eliminar los primeros n elementos de un iterable:

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

Es ligeramente más rápido que usar deque(..., maxlen=0) porque solo hace una llamada al next método de islice .

 for root, dirs, files in os.walk(dir).__next__()[1]: