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?
ValueError: zero length field name in format
est jeté.root.replace(startpath, '', 1)
devrait résoudre ce problèmeSimilaire aux réponses ci-dessus, mais pour python3, sans doute lisible et sans doute extensible:
Exemple d'utilisation:
Exemple de sortie:
Remarques
Éditer:
la source
Une solution sans votre indentation:
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.
la source
NameError: name 'path' is not defined
Nous préférons généralement utiliser l'arborescence GNU, mais nous n'en avons pas toujours
tree
sur 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 GNUtree
une exigence.tree
La sortie de ressemble à ceci: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
Path
objet Python 3yield
etyield from
(qui créent une fonction de générateur)et maintenant:
imprime:
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
tree
nous donne quelques fonctionnalités utiles que j'aimerais avoir avec cette fonction:n directories, m files
-L level
-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 - disons1000
.Supprimons donc les commentaires précédents et remplissons cette fonctionnalité:
Et maintenant, nous pouvons obtenir le même type de sortie que
tree
:imprime:
Et nous pouvons nous limiter aux niveaux:
imprime:
Et nous pouvons limiter la sortie aux répertoires:
imprime:
Rétrospective
Rétrospectivement, nous aurions pu utiliser
path.glob
pour l'appariement. Nous pourrions peut-être aussi l'utiliserpath.rglob
pour le globbing récursif, mais cela nécessiterait une réécriture. Nous pourrions également utiliseritertools.tee
au 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!
la source
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é.contents
doit être filtré si la valeurlimit_to_directories
est 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()]
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 lesiterdir()
commandes ou est garanti pour fournir la commande souhaité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. "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.
la source
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
la source
Si quelqu'un est intéressé - cette fonction récursive renvoie la structure imbriquée des dictionnaires. Les clés sont des
file system
noms (de répertoires et de fichiers), les valeurs sont soit: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:
Le résultat sera:
Si vous aimez ça, j'ai déjà créé un package (python 2 & 3) avec ce truc (et une belle
pyfakefs
aide): https://pypi.org/project/fsforge/la source
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):
la source
Vous pouvez exécuter la commande 'tree' du shell Linux.
Installation:
Utilisation en python
Exemple:
Cela vous donne une structure plus propre et est visuellement plus complète et facile à taper.
la source
Cette solution ne fonctionnera que si vous l'avez
tree
installé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 aveclxml
.Avec la structure de répertoires suivante à titre d'exemple:
XML
JSON
la source
Peut-être plus rapide que @ellockie (peut-être)
Résultats des tests dans la capture d'écran ci-dessous:
la source
Ici vous pouvez trouver du code avec une sortie comme celle-ci: https://stackoverflow.com/a/56622847/6671330
la source
Pour ceux qui recherchent encore une réponse. Voici une approche récursive pour obtenir les chemins dans un dictionnaire.
la source
La réponse de @ dhobbs est géniale!
mais changez simplement pour obtenir facilement les informations de niveau
et la sortie comme
vous pouvez obtenir le niveau par
|
décompte!la source