web-dev-qa-db-fra.com

os.walk sans fouiller dans les répertoires ci-dessous

Comment est-ce que je limite os.walk pour ne renvoyer que des fichiers dans le répertoire que je fournis?

def _dir_list(self, dir_name, whitelist):
    outputList = []
    for root, dirs, files in os.walk(dir_name):
        for f in files:
            if os.path.splitext(f)[1] in whitelist:
                outputList.append(os.path.join(root, f))
            else:
                self._email_to_("ignore")
    return outputList
81
Setori

Utilisez la fonction walklevel.

import os

def walklevel(some_dir, level=1):
    some_dir = some_dir.rstrip(os.path.sep)
    assert os.path.isdir(some_dir)
    num_sep = some_dir.count(os.path.sep)
    for root, dirs, files in os.walk(some_dir):
        yield root, dirs, files
        num_sep_this = root.count(os.path.sep)
        if num_sep + level <= num_sep_this:
            del dirs[:]

Cela fonctionne comme os.walk, mais vous pouvez lui transmettre un paramètre level qui indique la profondeur de la récursivité.

87
nosklo

N'utilisez pas os.walk.

Exemple:

import os

root = "C:\\"
for item in os.listdir(root):
    if os.path.isfile(os.path.join(root, item)):
        print item
177
Yuval Adam

Je pense que la solution est en réalité très simple.

utilisation 

break

pour ne faire que la première itération de la boucle for, il doit y avoir un moyen plus élégant.

for root, dirs, files in os.walk(dir_name):
    for f in files:
        ...
        ...
    break
...

La première fois que vous appelez os.walk, il renvoie des tulipes pour le répertoire actuel, puis boucle le contenu du répertoire suivant. 

Prenez le script original et ajoutez simplement un break .

def _dir_list(self, dir_name, whitelist):
    outputList = []
    for root, dirs, files in os.walk(dir_name):
        for f in files:
            if os.path.splitext(f)[1] in whitelist:
                outputList.append(os.path.join(root, f))
            else:
                self._email_to_("ignore")
        break
    return outputList
34
Pieter

La suggestion d'utiliser listdir est bonne. La réponse directe à votre question dans Python 2 est root, dirs, files = os.walk(dir_name).next().

La syntaxe équivalente de Python 3 est root, dirs, files = next(os.walk(dir_name))

18
Alex Coventry

Vous pouvez utiliser os.listdir() qui renvoie une liste de noms (pour les fichiers et les répertoires) dans un répertoire donné. Si vous devez faire la distinction entre les fichiers et les répertoires, appelez os.stat() pour chaque nom.

10
Greg Hewgill

Si vous avez des exigences plus complexes que celle du répertoire principal (par exemple, ignorer les répertoires VCS, etc.), vous pouvez également modifier la liste des répertoires pour empêcher os.walk de les parcourir de manière récurrente.

c'est à dire:

def _dir_list(self, dir_name, whitelist):
    outputList = []
    for root, dirs, files in os.walk(dir_name):
        dirs[:] = [d for d in dirs if is_good(d)]
        for f in files:
            do_stuff()

Remarque: veillez à modifier la liste au lieu de la renvoyer. De toute évidence, os.walk ne connaît pas la reconnexion externe.

9
Brian

La même idée avec listdir, mais plus courte:

[f for f in os.listdir(root_dir) if os.path.isfile(os.path.join(root_dir, f))]
4
Oleg Gryb

Envie de jeter mes 2 pence.

baselevel = len(rootdir.split("\\"))
for subdirs, dirs, files in os.walk(rootdir):
    curlevel = len(subdirs.split("\\"))
    if curlevel <= baselevel + 1:
        [do stuff]
3
Matt R

En Python 3, j'ai pu faire ceci:

import os
dir = "/path/to/files/"

#List all files immediately under this folder:
print ( next( os.walk(dir) )[2] )

#List all folders immediately under this folder:
print ( next( os.walk(dir) )[1] )
2
Jay Sheth
for path, dirs, files in os.walk('.'):
    print path, dirs, files
    del dirs[:] # go only one level deep
2
masterxilo

Vous pouvez également faire ce qui suit:

for path, subdirs, files in os.walk(dir_name):
    for name in files:
        if path == ".": #this will filter the files in the current directory
             #code here
1
Diana G

Depuis Python 3.5 , vous pouvez utiliser os.scandir au lieu de os.listdir . Au lieu de chaînes, vous obtenez un itérateur de DirEntry objets en retour. De la docs:

L'utilisation de scandir() au lieu de listdir() peut considérablement améliorer les performances du code qui a également besoin d'informations de type ou d'attributs de fichier, car les objets DirEntry exposent ces informations si le système d'exploitation les fournit lors de l'analyse d'un répertoire. Toutes les méthodes DirEntry peuvent effectuer un appel système, mais is_dir() et is_file() ne requièrent généralement qu'un appel système pour les liens symboliques; DirEntry.stat() nécessite toujours un appel système sous Unix mais un seul pour les liens symboliques sous Windows.

Vous pouvez accéder au nom de l'objet via _DirEntry.name_ qui est alors équivalent à la sortie de _os.listdir_

0
ascripter

le dossier racine change pour chaque répertoire trouvé par os.walk. Je résous que vérifier si root == répertoire

def _dir_list(self, dir_name, whitelist):
    outputList = []
    for root, dirs, files in os.walk(dir_name):
        if root == dir_name: #This only meet parent folder
            for f in files:
                if os.path.splitext(f)[1] in whitelist:
                    outputList.append(os.path.join(root, f))
                else:
                    self._email_to_("ignore")
    return outputList
0
Pedro J. Sola

Voici comment je l'ai résolu

if recursive:
    items = os.walk(target_directory)
else:
    items = [next(os.walk(target_directory))]

...
0
Deifyed

créer une liste d'exclusions, utilisez fnmatch pour ignorer la structure de répertoires et effectuer le processus

excludes= ['a\*\b', 'c\d\e']
for root, directories, files in os.walk('Start_Folder'):
    if not any(fnmatch.fnmatch(nf_root, pattern) for pattern in excludes):
        for root, directories, files in os.walk(nf_root):
            ....
            do the process
            ....

idem que pour 'comprend':

if **any**(fnmatch.fnmatch(nf_root, pattern) for pattern in **includes**):
0
Hamsavardhini

Il y a un problème lors de l'utilisation de listdir. Os.path.isdir (identifiant) doit être un chemin absolu. Pour choisir les sous-répertoires que vous faites:

for dirname in os.listdir(rootdir):
  if os.path.isdir(os.path.join(rootdir, dirname)):
     print("I got a subdirectory: %s" % dirname)

L'alternative consiste à accéder au répertoire pour effectuer les tests sans os.path.join ().

0
Kemin Zhou

Vous pouvez utiliser cet extrait

for root, dirs, files in os.walk(directory):
    if level > 0:
        # do some stuff
    else:
        break
    level-=1
0
RousseauAlexandre

Pourquoi ne pas simplement utiliser une range et os.walk combinés avec la Zip? N'est-ce pas la meilleure solution, mais fonctionnerait aussi.

Par exemple, comme ceci:

# your part before
for count, (root, dirs, files) in Zip(range(0, 1), os.walk(dir_name)):
    # logic stuff
# your later part

Fonctionne pour moi sur Python 3.

Aussi: Une break est plus simple aussi. (Regardez la réponse de @Pieter)

0
PiMathCLanguage