Liste de l'arborescence des répertoires en python?


111

Je sais que nous pouvons utiliser os.walk()pour lister tous les sous-répertoires ou tous les fichiers d'un répertoire. Cependant, je voudrais lister le contenu complet de l'arborescence de répertoires:

- Subdirectory 1:
   - file11
   - file12
   - Sub-sub-directory 11:
         - file111
         - file112
- Subdirectory 2:
    - file21
    - sub-sub-directory 21
    - sub-sub-directory 22    
        - sub-sub-sub-directory 221
            - file 2211

Comment y parvenir au mieux en Python?

Réponses:


146

Voici une fonction pour faire cela avec le formatage:

import os

def list_files(startpath):
    for root, dirs, files in os.walk(startpath):
        level = root.replace(startpath, '').count(os.sep)
        indent = ' ' * 4 * (level)
        print('{}{}/'.format(indent, os.path.basename(root)))
        subindent = ' ' * 4 * (level + 1)
        for f in files:
            print('{}{}'.format(subindent, f))

1
Cela a très bien fonctionné, merci. Bien que la plupart le sachent, toujours pour le bénéfice des nouveaux arrivants dans python - veuillez noter que vous devrez appeler la fonction à la fin (en supposant que Windows), vous pouvez donc ajouter une nouvelle ligne à la fin avec le contenu list_files ("D: \\ ")
Rahul

1
A bien fonctionné sur python3. Mais sur python2 ValueError: zero length field name in formatest jeté.
nipunasudha

3
Si startpath est répété dans root, ne remplacera-t-il pas chaque occurrence? Changer pour root.replace(startpath, '', 1)devrait résoudre ce problème
drone.ah

31

Similaire aux réponses ci-dessus, mais pour python3, sans doute lisible et sans doute extensible:

from pathlib import Path

class DisplayablePath(object):
    display_filename_prefix_middle = '├──'
    display_filename_prefix_last = '└──'
    display_parent_prefix_middle = '    '
    display_parent_prefix_last = '│   '

    def __init__(self, path, parent_path, is_last):
        self.path = Path(str(path))
        self.parent = parent_path
        self.is_last = is_last
        if self.parent:
            self.depth = self.parent.depth + 1
        else:
            self.depth = 0

    @property
    def displayname(self):
        if self.path.is_dir():
            return self.path.name + '/'
        return self.path.name

    @classmethod
    def make_tree(cls, root, parent=None, is_last=False, criteria=None):
        root = Path(str(root))
        criteria = criteria or cls._default_criteria

        displayable_root = cls(root, parent, is_last)
        yield displayable_root

        children = sorted(list(path
                               for path in root.iterdir()
                               if criteria(path)),
                          key=lambda s: str(s).lower())
        count = 1
        for path in children:
            is_last = count == len(children)
            if path.is_dir():
                yield from cls.make_tree(path,
                                         parent=displayable_root,
                                         is_last=is_last,
                                         criteria=criteria)
            else:
                yield cls(path, displayable_root, is_last)
            count += 1

    @classmethod
    def _default_criteria(cls, path):
        return True

    @property
    def displayname(self):
        if self.path.is_dir():
            return self.path.name + '/'
        return self.path.name

    def displayable(self):
        if self.parent is None:
            return self.displayname

        _filename_prefix = (self.display_filename_prefix_last
                            if self.is_last
                            else self.display_filename_prefix_middle)

        parts = ['{!s} {!s}'.format(_filename_prefix,
                                    self.displayname)]

        parent = self.parent
        while parent and parent.parent is not None:
            parts.append(self.display_parent_prefix_middle
                         if parent.is_last
                         else self.display_parent_prefix_last)
            parent = parent.parent

        return ''.join(reversed(parts))

Exemple d'utilisation:

paths = DisplayablePath.make_tree(Path('doc'))
for path in paths:
    print(path.displayable())

Exemple de sortie:

doc/
├── _static/
   ├── embedded/
      ├── deep_file
      └── very/
          └── deep/
              └── folder/
                  └── very_deep_file
   └── less_deep_file
├── about.rst
├── conf.py
└── index.rst

Remarques

  • Cela utilise la récursivité. Cela lèvera une RecursionError sur les arborescences de dossiers vraiment profondes
  • L'arbre est évalué paresseusement. Il devrait bien se comporter sur des arborescences de dossiers très larges . Cependant, les enfants immédiats d'un dossier donné ne sont pas évalués paresseusement.

Éditer:

  • Bonus supplémentaire! critères de rappel pour filtrer les chemins.

Bel outil, avez-vous un exemple rapide sur la façon d'utiliser des critères pour exclure les noms de dossier?
Matt-Mac-Muffin

Ceci est exactement ce que je cherchais. Merci beaucoup!
dheinz le

24

Une solution sans votre indentation:

for path, dirs, files in os.walk(given_path):
  print path
  for f in files:
    print f

os.walk effectue déjà la marche descendante et en profondeur que vous recherchez.

Ignorer la liste des répertoires empêche le chevauchement que vous mentionnez.


2
python dit:NameError: name 'path' is not defined
Francesco Mantovani

1
@FrancescoMantovani "path" est la variable contenant le répertoire que vous souhaitez imprimer, c'est-à-dire r "C: \ Users \ username \ Documents \ path"
zwelz

16

Liste de l'arborescence des répertoires en Python?

Nous préférons généralement utiliser l'arborescence GNU, mais nous n'en avons pas toujours treesur tous les systèmes, et parfois Python 3 est disponible. Une bonne réponse ici pourrait être facilement copiée et ne pas faire de GNU treeune exigence.

treeLa sortie de ressemble à ceci:

$ tree
.
├── package
   ├── __init__.py
   ├── __main__.py
   ├── subpackage
      ├── __init__.py
      ├── __main__.py
      └── module.py
   └── subpackage2
       ├── __init__.py
       ├── __main__.py
       └── module2.py
└── package2
    └── __init__.py

4 directories, 9 files

J'ai créé la structure de répertoires ci-dessus dans mon répertoire personnel sous un répertoire que j'appelle pyscratch.

Je vois également d'autres réponses ici qui abordent ce genre de sortie, mais je pense que nous pouvons faire mieux, avec un code plus simple et plus moderne et des approches d'évaluation paresseuses.

Arbre en Python

Pour commencer, utilisons un exemple qui

  • utilise l' Pathobjet Python 3
  • utilise les expressions yieldet yield from(qui créent une fonction de générateur)
  • utilise la récursivité pour une simplicité élégante
  • utilise des commentaires et des annotations de type pour plus de clarté
from pathlib import Path

# prefix components:
space =  '    '
branch = '│   '
# pointers:
tee =    '├── '
last =   '└── '


def tree(dir_path: Path, prefix: str=''):
    """A recursive generator, given a directory Path object
    will yield a visual tree structure line by line
    with each line prefixed by the same characters
    """    
    contents = list(dir_path.iterdir())
    # contents each get pointers that are ├── with a final └── :
    pointers = [tee] * (len(contents) - 1) + [last]
    for pointer, path in zip(pointers, contents):
        yield prefix + pointer + path.name
        if path.is_dir(): # extend the prefix and recurse:
            extension = branch if pointer == tee else space 
            # i.e. space because last, └── , above so no more |
            yield from tree(path, prefix=prefix+extension)

et maintenant:

for line in tree(Path.home() / 'pyscratch'):
    print(line)

imprime:

├── package
   ├── __init__.py
   ├── __main__.py
   ├── subpackage
      ├── __init__.py
      ├── __main__.py
      └── module.py
   └── subpackage2
       ├── __init__.py
       ├── __main__.py
       └── module2.py
└── package2
    └── __init__.py

Nous avons besoin de matérialiser chaque répertoire dans une liste parce que nous avons besoin de savoir combien de temps il dure, mais ensuite nous jetons la liste. Pour une récursion profonde et large, cela devrait être assez paresseux.

Le code ci-dessus, avec les commentaires, devrait être suffisant pour bien comprendre ce que nous faisons ici, mais n'hésitez pas à le parcourir avec un débogueur pour mieux le faire si vous en avez besoin.

Plus de fonctionnalités

Maintenant, GNU treenous donne quelques fonctionnalités utiles que j'aimerais avoir avec cette fonction:

  • imprime d'abord le nom du répertoire sujet (le fait automatiquement, le nôtre ne le fait pas)
  • imprime le nombre de n directories, m files
  • option pour limiter la récursivité, -L level
  • possibilité de se limiter aux répertoires, -d

De plus, quand il y a un arbre énorme, il est utile de limiter l'itération (par exemple avec islice) pour éviter de bloquer votre interpréteur avec du texte, car à un moment donné la sortie devient trop verbeuse pour être utile. Nous pouvons rendre cela arbitrairement élevé par défaut - disons 1000.

Supprimons donc les commentaires précédents et remplissons cette fonctionnalité:

from pathlib import Path
from itertools import islice

space =  '    '
branch = '│   '
tee =    '├── '
last =   '└── '
def tree(dir_path: Path, level: int=-1, limit_to_directories: bool=False,
         length_limit: int=1000):
    """Given a directory Path object print a visual tree structure"""
    dir_path = Path(dir_path) # accept string coerceable to Path
    files = 0
    directories = 0
    def inner(dir_path: Path, prefix: str='', level=-1):
        nonlocal files, directories
        if not level: 
            return # 0, stop iterating
        if limit_to_directories:
            contents = [d for d in dir_path.iterdir() if d.is_dir()]
        else: 
            contents = list(dir_path.iterdir())
        pointers = [tee] * (len(contents) - 1) + [last]
        for pointer, path in zip(pointers, contents):
            if path.is_dir():
                yield prefix + pointer + path.name
                directories += 1
                extension = branch if pointer == tee else space 
                yield from inner(path, prefix=prefix+extension, level=level-1)
            elif not limit_to_directories:
                yield prefix + pointer + path.name
                files += 1
    print(dir_path.name)
    iterator = inner(dir_path, level=level)
    for line in islice(iterator, length_limit):
        print(line)
    if next(iterator, None):
        print(f'... length_limit, {length_limit}, reached, counted:')
    print(f'\n{directories} directories' + (f', {files} files' if files else ''))

Et maintenant, nous pouvons obtenir le même type de sortie que tree:

tree(Path.home() / 'pyscratch')

imprime:

pyscratch
├── package
   ├── __init__.py
   ├── __main__.py
   ├── subpackage
      ├── __init__.py
      ├── __main__.py
      └── module.py
   └── subpackage2
       ├── __init__.py
       ├── __main__.py
       └── module2.py
└── package2
    └── __init__.py

4 directories, 9 files

Et nous pouvons nous limiter aux niveaux:

tree(Path.home() / 'pyscratch', level=2)

imprime:

pyscratch
├── package
   ├── __init__.py
   ├── __main__.py
   ├── subpackage
   └── subpackage2
└── package2
    └── __init__.py

4 directories, 3 files

Et nous pouvons limiter la sortie aux répertoires:

tree(Path.home() / 'pyscratch', level=2, limit_to_directories=True)

imprime:

pyscratch
├── package
   ├── subpackage
   └── subpackage2
└── package2

4 directories

Rétrospective

Rétrospectivement, nous aurions pu utiliser path.globpour l'appariement. Nous pourrions peut-être aussi l'utiliser path.rglobpour le globbing récursif, mais cela nécessiterait une réécriture. Nous pourrions également utiliser itertools.teeau lieu de matérialiser une liste de contenus de répertoires, mais cela pourrait avoir des compromis négatifs et rendrait probablement le code encore plus complexe.

Les commentaires sont les bienvenus!


Pour imprimer également les lignes de code, après elif not limit_to_directories:ajouter ce qui suit: info = prefix + pointer + path.name; try: with path.open('r') as f: n_lines = len(f.readlines()); loc = f' LOC: {n_lines}'; info += loc; except UnicodeDecodeError: pass; yield info Voir ce lien pour un espace blanc approprié.
Steven C. Howell

C'était exactement ce dont j'avais besoin dans mon code et cela m'a appris de nouvelles astuces Python! La seule chose que je noterais est qu'il contentsdoit être filtré si la valeur limit_to_directoriesest True. Sinon, si un dossier n'a pas de répertoire pour le dernier fichier, l'arborescence ne sera pas dessinée correctement. if limit_to_directories: contents = [path for path in contents if path.is_dir()]
hennign

@hennign merci, réponse mise à jour, appréciez les commentaires!
Aaron Hall

Python est entièrement basé sur le list(dir_path.iterdir())retour d'une arborescence descendante correctement ordonnée de la structure de répertoires. Je ne vois aucune garantie de ce type dans l' API pour iterdir () . Veuillez fournir une référence sur la façon dont les iterdir()commandes ou est garanti pour fournir la commande souhaitée.
ingyhere

@ingyhere Je ne sais pas d'où vous avez eu cette idée - elle semble être utilisée os.listdir()par défaut - qui ne garantit pas l'ordre : "La liste est dans un ordre arbitraire et n'inclut pas les entrées spéciales '.' et '..' même s'ils sont présents dans le répertoire. "
Aaron Hall

15

Je suis venu ici à la recherche de la même chose et j'ai utilisé la réponse dhobbs pour moi. Pour remercier la communauté, j'ai ajouté quelques arguments pour écrire dans un fichier, comme l'akshay l'a demandé, et j'ai rendu l'affichage des fichiers facultatif afin que ce ne soit pas si peu une sortie. Également fait de l'indentation un argument facultatif afin que vous puissiez le modifier, car certains l'aiment comme 2 et d'autres préfèrent 4.

Utilisé différentes boucles pour que celle qui n'affiche pas les fichiers ne vérifie pas si elle doit le faire à chaque itération.

J'espère que cela aide quelqu'un d'autre, car la réponse de dhobbs m'a aidé. Merci beaucoup.

def showFolderTree(path,show_files=False,indentation=2,file_output=False):
"""
Shows the content of a folder in a tree structure.
path -(string)- path of the root folder we want to show.
show_files -(boolean)-  Whether or not we want to see files listed.
                        Defaults to False.
indentation -(int)- Indentation we want to use, defaults to 2.   
file_output -(string)-  Path (including the name) of the file where we want
                        to save the tree.
"""


tree = []

if not show_files:
    for root, dirs, files in os.walk(path):
        level = root.replace(path, '').count(os.sep)
        indent = ' '*indentation*(level)
        tree.append('{}{}/'.format(indent,os.path.basename(root)))

if show_files:
    for root, dirs, files in os.walk(path):
        level = root.replace(path, '').count(os.sep)
        indent = ' '*indentation*(level)
        tree.append('{}{}/'.format(indent,os.path.basename(root)))    
        for f in files:
            subindent=' ' * indentation * (level+1)
            tree.append('{}{}'.format(subindent,f))

if file_output:
    output_file = open(file_output,'w')
    for line in tree:
        output_file.write(line)
        output_file.write('\n')
else:
    # Default behaviour: print on screen.
    for line in tree:
        print line

Je pense que cette réponse ne contribue pas à la réponse déjà acceptée. La seule chose que vous fournissez est un code supplémentaire pour désactiver les fonctionnalités ou non dans la réponse.
CodeLikeBeaker

3
Votre sentiment est juste, @ jason-heine. La réponse acceptée est assez bonne, mais certaines personnes ont demandé comment faire ce truc de duvet et je voulais leur donner quelque chose. Évitez le vote ou rapportez ma réponse si vous ne voulez pas voir cela dans SO, je pensais que cela ne ferait pas de mal, mais je me trompe peut-être.
Rubén Cabrera

3
C'est vraiment utile. Merci beaucoup. Je l'ai utilisé tel quel.
vladblindu

7

Basé sur ce post fantastique

http://code.activestate.com/recipes/217212-treepy-graphically-displays-the-directory-structur/

Voici un raffinement pour se comporter exactement comme

http://linux.die.net/man/1/tree

#! / usr / bin / env python2 # - * - codage: utf-8 - * -


# tree.py # # Écrit par Doug Dahms # # Imprime l'arborescence du chemin spécifié sur la ligne de commande





depuis os import listdir , sep
 depuis os . chemin import abspath , basename , isdir
 depuis sys import argv

arbre def ( dir , padding , print_files = False , isLast = False , isFirst = False ): if isFirst : print padding . decode ( 'utf8' ) [: - 1 ]. encode ( 'utf8' ) + dir
     else : if isLast : remplissage d' impression . decode ( 'utf8' ) [: - 1 ].
    
         
        
            encode ( 'utf8' ) + '└──' + basename ( abspath ( dir )) else : remplissage d' impression . decode ( 'utf8' ) [: - 1 ]. encode ( 'utf8' ) + '├──' + basename ( abspath ( dir )) 
    files = [] if print_files : 
        files = listdir ( dir ) else :   
        
                
    
    
        fichiers = [ x pour x dans listdir ( dir ) si isdir ( dir + septembre + x )] si non isFirst : 
        rembourrage = padding + '' 
    fichiers = triés ( fichiers , clé = lambda s : s . bas ()) 
    compte = 0 
    dernier = len (  
       files ) - 1 pour i , fichier dans enumerate ( fichiers ): 
        count + = 1 
        chemin = dir + sep + fichier  
     
        isLast = i == last
         if isdir ( path ): if count == len ( files ): if isFirst : 
                    tree ( path , padding , print_files , isLast , False ) else : 
                    tree ( path , padding + '' , print_files , isLast) , Faux )
            
                 
                  
            else:
                tree(path, padding + '│', print_files, isLast, False)
        else:
            if isLast:
                print padding + '└── ' + file
            else:
                print padding + '├── ' + file

def usage():
    return '''Usage: %s [-f] 
Print tree structure of path specified.
Options:
-f      Print files as well as directories
PATH    Path to process''' % basename(argv[0])

def main():
    if len(argv) == 1:
        print usage()
    elif len(argv) == 2:
        # print just directories
        path = argv[1]
        if isdir(path):
            tree(path, '', False, False, True)
        else:
            print 'ERROR: \'' + path + '\' is not a directory'
    elif len(argv) == 3 and argv[1] == '-f':
        # print directories and files
        path = argv[2]
        if isdir(path):
            tree(path, '', True, False, True)
        else:
            print 'ERROR: \'' + path + '\' n'est pas un répertoire ' else : print usage ()
    
        

si __nom__ == '__main__' : 
    main () 


6
import os

def fs_tree_to_dict(path_):
    file_token = ''
    for root, dirs, files in os.walk(path_):
        tree = {d: fs_tree_to_dict(os.path.join(root, d)) for d in dirs}
        tree.update({f: file_token for f in files})
        return tree  # note we discontinue iteration trough os.walk

Si quelqu'un est intéressé - cette fonction récursive renvoie la structure imbriquée des dictionnaires. Les clés sont des file systemnoms (de répertoires et de fichiers), les valeurs sont soit:

  • sous-dictionnaires pour les répertoires
  • chaînes pour les fichiers (voir file_token)

Les chaînes désignant les fichiers sont vides dans cet exemple. Ils peuvent également être, par exemple, le contenu d'un fichier donné ou ses informations de propriétaire ou ses privilèges ou tout autre objet différent d'un dict. À moins qu'il ne s'agisse d'un dictionnaire, il peut être facilement distingué d'un "type de répertoire" dans d'autres opérations.

Avoir un tel arbre dans un système de fichiers:

# bash:
$ tree /tmp/ex
/tmp/ex
├── d_a
   ├── d_a_a
   ├── d_a_b
      └── f1.txt
   ├── d_a_c
   └── fa.txt
├── d_b
   ├── fb1.txt
   └── fb2.txt
└── d_c

Le résultat sera:

# python 2 or 3:
>>> fs_tree_to_dict("/tmp/ex")
{
    'd_a': {
        'd_a_a': {},
        'd_a_b': {
            'f1.txt': ''
        },
        'd_a_c': {},
        'fa.txt': ''
    },
    'd_b': {
        'fb1.txt': '',
        'fb2.txt': ''
    },
    'd_c': {}
}

Si vous aimez ça, j'ai déjà créé un package (python 2 & 3) avec ce truc (et une belle pyfakefsaide): https://pypi.org/project/fsforge/


4

En plus de la réponse dhobbs ci-dessus ( https://stackoverflow.com/a/9728478/624597 ), voici une fonctionnalité supplémentaire de stockage des résultats dans un fichier (je l'utilise personnellement pour copier et coller dans FreeMind pour avoir un bon aperçu de la structure, donc j'ai utilisé des tabulations au lieu d'espaces pour l'indentation):

import os

def list_files(startpath):

    with open("folder_structure.txt", "w") as f_output:
        for root, dirs, files in os.walk(startpath):
            level = root.replace(startpath, '').count(os.sep)
            indent = '\t' * 1 * (level)
            output_string = '{}{}/'.format(indent, os.path.basename(root))
            print(output_string)
            f_output.write(output_string + '\n')
            subindent = '\t' * 1 * (level + 1)
            for f in files:
                output_string = '{}{}'.format(subindent, f)
                print(output_string)
                f_output.write(output_string + '\n')

list_files(".")

cette réponse a vraiment aidé, merci
prex le

2

Vous pouvez exécuter la commande 'tree' du shell Linux.

Installation:

   ~$sudo apt install tree

Utilisation en python

    >>> import os
    >>> os.system('tree <desired path>')

Exemple:

    >>> os.system('tree ~/Desktop/myproject')

Cela vous donne une structure plus propre et est visuellement plus complète et facile à taper.


Ce n'est pas une solution très portable car cela échoue sur Windows + repose sur un programme supplémentaire
oglop

2

Cette solution ne fonctionnera que si vous l'avez treeinstallée sur votre système. Cependant, je laisse cette solution ici au cas où cela aiderait quelqu'un d'autre.

Vous pouvez indiquer à tree de générer la structure arborescente au format XML ( tree -X) ou JSON ( tree -J). JSON bien sûr peut être analysé directement avec python et XML peut être facilement lu avec lxml.

Avec la structure de répertoires suivante à titre d'exemple:

[sri@localhost Projects]$ tree --charset=ascii bands
bands
|-- DreamTroll
|   |-- MattBaldwinson
|   |-- members.txt
|   |-- PaulCarter
|   |-- SimonBlakelock
|   `-- Rob Stringer
|-- KingsX
|   |-- DougPinnick
|   |-- JerryGaskill
|   |-- members.txt
|   `-- TyTabor
|-- Megadeth
|   |-- DaveMustaine
|   |-- DavidEllefson
|   |-- DirkVerbeuren
|   |-- KikoLoureiro
|   `-- members.txt
|-- Nightwish
|   |-- EmppuVuorinen
|   |-- FloorJansen
|   |-- JukkaNevalainen
|   |-- MarcoHietala
|   |-- members.txt
|   |-- TroyDonockley
|   `-- TuomasHolopainen
`-- Rush
    |-- AlexLifeson
    |-- GeddyLee
    `-- NeilPeart

5 directories, 25 files

XML

<?xml version="1.0" encoding="UTF-8"?>
<tree>
  <directory name="bands">
    <directory name="DreamTroll">
      <file name="MattBaldwinson"></file>
      <file name="members.txt"></file>
      <file name="PaulCarter"></file>
      <file name="RobStringer"></file>
      <file name="SimonBlakelock"></file>
    </directory>
    <directory name="KingsX">
      <file name="DougPinnick"></file>
      <file name="JerryGaskill"></file>
      <file name="members.txt"></file>
      <file name="TyTabor"></file>
    </directory>
    <directory name="Megadeth">
      <file name="DaveMustaine"></file>
      <file name="DavidEllefson"></file>
      <file name="DirkVerbeuren"></file>
      <file name="KikoLoureiro"></file>
      <file name="members.txt"></file>
    </directory>
    <directory name="Nightwish">
      <file name="EmppuVuorinen"></file>
      <file name="FloorJansen"></file>
      <file name="JukkaNevalainen"></file>
      <file name="MarcoHietala"></file>
      <file name="members.txt"></file>
      <file name="TroyDonockley"></file>
      <file name="TuomasHolopainen"></file>
    </directory>
    <directory name="Rush">
      <file name="AlexLifeson"></file>
      <file name="GeddyLee"></file>
      <file name="NeilPeart"></file>
    </directory>
  </directory>
  <report>
    <directories>5</directories>
    <files>25</files>
  </report>
</tree>

JSON

[sri@localhost Projects]$ tree -J bands
[
  {"type":"directory","name":"bands","contents":[
    {"type":"directory","name":"DreamTroll","contents":[
      {"type":"file","name":"MattBaldwinson"},
      {"type":"file","name":"members.txt"},
      {"type":"file","name":"PaulCarter"},
      {"type":"file","name":"RobStringer"},
      {"type":"file","name":"SimonBlakelock"}
    ]},
    {"type":"directory","name":"KingsX","contents":[
      {"type":"file","name":"DougPinnick"},
      {"type":"file","name":"JerryGaskill"},
      {"type":"file","name":"members.txt"},
      {"type":"file","name":"TyTabor"}
    ]},
    {"type":"directory","name":"Megadeth","contents":[
      {"type":"file","name":"DaveMustaine"},
      {"type":"file","name":"DavidEllefson"},
      {"type":"file","name":"DirkVerbeuren"},
      {"type":"file","name":"KikoLoureiro"},
      {"type":"file","name":"members.txt"}
    ]},
    {"type":"directory","name":"Nightwish","contents":[
      {"type":"file","name":"EmppuVuorinen"},
      {"type":"file","name":"FloorJansen"},
      {"type":"file","name":"JukkaNevalainen"},
      {"type":"file","name":"MarcoHietala"},
      {"type":"file","name":"members.txt"},
      {"type":"file","name":"TroyDonockley"},
      {"type":"file","name":"TuomasHolopainen"}
    ]},
    {"type":"directory","name":"Rush","contents":[
      {"type":"file","name":"AlexLifeson"},
      {"type":"file","name":"GeddyLee"},
      {"type":"file","name":"NeilPeart"}
    ]}
  ]},
  {"type":"report","directories":5,"files":25}
]

1

Peut-être plus rapide que @ellockie (peut-être)

importer le système d'exploitation
def file_writer (texte):
    avec open ("folder_structure.txt", "a") comme f_output:
        f_output.write (texte)
def list_files (startpath):


    pour root, dirs, fichiers dans os.walk (startpath):
        level = root.replace (startpath, '') .count (os.sep)
        indent = '\ t' * 1 * (niveau)
        output_string = '{} {} / \ n'.format (retrait, os.path.basename (racine))
        file_writer (chaîne_sortie)
        subindent = '\ t' * 1 * (niveau + 1)
        output_string = '% s% s \ n'% (sous-index, [f pour f dans les fichiers])
        file_writer (''. join (chaîne_sortie))


list_files ("/")

Résultats des tests dans la capture d'écran ci-dessous:

entrez la description de l'image ici


0

Ici vous pouvez trouver du code avec une sortie comme celle-ci: https://stackoverflow.com/a/56622847/6671330

V .
|-> V folder1
|   |-> V folder2
|   |   |-> V folder3
|   |   |   |-> file3.txt
|   |   |-> file2.txt
|   |-> V folderX
|   |-> file1.txt
|-> 02-hw1_wdwwfm.py
|-> 06-t1-home1.py
|-> 06-t1-home2.py
|-> hw1.py

0

Pour ceux qui recherchent encore une réponse. Voici une approche récursive pour obtenir les chemins dans un dictionnaire.

import os


def list_files(startpath):
    for root, dirs, files in os.walk(startpath):
        dir_content = []
        for dir in dirs:
            go_inside = os.path.join(startpath, dir)
            dir_content.append(list_files(go_inside))
        files_lst = []
        for f in files:
            files_lst.append(f)
        return {'name': root, 'files': files_lst, 'dirs': dir_content}

0

La réponse de @ dhobbs est géniale!

mais changez simplement pour obtenir facilement les informations de niveau

def print_list_dir(dir):
    print("=" * 64)
    print("[PRINT LIST DIR] %s" % dir)
    print("=" * 64)
    for root, dirs, files in os.walk(dir):
        level = root.replace(dir, '').count(os.sep)
        indent = '| ' * level
        print('{}{} \\'.format(indent, os.path.basename(root)))
        subindent = '| ' * (level + 1)
        for f in files:
            print('{}{}'.format(subindent, f))
    print("=" * 64)

et la sortie comme

================================================================
[PRINT LIST DIR] ./
================================================================
 \
| os_name.py
| json_loads.py
| linspace_python.py
| list_file.py
| to_gson_format.py
| type_convert_test.py
| in_and_replace_test.py
| online_log.py
| padding_and_clipping.py
| str_tuple.py
| set_test.py
| script_name.py
| word_count.py
| get14.py
| np_test2.py
================================================================

vous pouvez obtenir le niveau par |décompte!

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.