Python glob plusieurs types de fichiers
Est-il une meilleure façon d'utiliser glob.glob en python pour obtenir une liste de plusieurs types de fichier comme .txt, .mdown, et .markdown? Maintenant j'ai quelque chose comme ceci:
projectFiles1 = glob.glob( os.path.join(projectDir, '*.txt') )
projectFiles2 = glob.glob( os.path.join(projectDir, '*.mdown') )
projectFiles3 = glob.glob( os.path.join(projectDir, '*.markdown') )
- Très en lien: stackoverflow.com/q/48181073/880783
Vous devez vous connecter pour publier un commentaire.
Peut-être il ya une meilleure façon, mais que diriez-vous:
Peut-être il ya une autre façon, afin d'attendre au cas où quelqu'un d'autre arrive avec une meilleure réponse.
files_grabbed = [glob.glob(e) for e in ['*.pdf', '*.cpp']]
[f for f_ in [glob.glob(e) for e in ('*.jpg', '*.mp4')] for f in f_]
Si vous devez spécifier un chemin d'accès, une boucle sur le match de motifs et de garder le rejoindre à l'intérieur de la boucle pour des raisons de simplicité:
De la chaîne des résultats:
Alors:
chain.from_iterable
. Donc, c'est semblable, mais moins lisible:it.chain(*(glob.iglob(pattern) for pattern in patterns))
.glob
renvoie une liste: pourquoi ne pas l'exécuter plusieurs fois et concaténer les résultats?ProjectFiles
àprojectFiles
, mais la bonne solution.avec glob il n'est pas possible. vous pouvez utiliser seulement à:
* correspond à tout ce qui
? correspond à tout caractère unique
[seq] correspond à tout caractère dans seq
[!seq] correspond à tout caractère qui n'est pas dans seq
utiliser os.listdir et une expression régulière pour vérifier les modèles:
itertools
car ultérieure motif des modifications doivent également être hacky (dites que vous voulez autoriser les majuscules et les minuscules). Oh, et il pourrait être plus propre d'écrire'.*\.(txt|sql)'
Par exemple, pour
*.mp3
et*.flac
sur plusieurs dossiers, vous pouvez faire:L'idée peut être étendue à plusieurs extensions de fichier, mais vous devez vérifier que les combinaisons ne correspondent à aucun indésirables extension de fichier que vous pouvez avoir sur ces dossiers. Donc, être prudent avec cette.
Pour combiner automatiquement un arbitraire liste des extensions en un seul glob modèle, vous pouvez effectuer les opérations suivantes:
Après de venir ici pour de l'aide, j'ai fait ma propre solution et je voulais le partager. Il est basé sur user2363986 réponse, mais je pense que c'est plus évolutif. Ce qui signifie que si vous avez 1000 extensions, le code sera toujours un peu l'air élégant.
directoryPath = "/Users/bla/bla/images_dir*."
Un one-liner, Juste pour l'enfer de celui-ci..
de sortie:
C'est un Python 3.4+
pathlib
solution:Aussi il ignore tous les noms de fichiers commençant par
~
.Ici est d'une ligne à la liste de compréhension de la variante de la Pat de la réponse (qui comprend aussi que tu voulais glob dans un répertoire du projet):
Vous en boucle sur les extensions (
for ext in exts
), puis pour chaque extension que vous prenez chaque fichier correspondant à la glob modèle (for f in glob.glob(os.path.join(project_dir, ext)
).Cette solution est court, et sans aucune inutiles pour des boucles imbriquées liste des compréhensions, des fonctions ou à l'encombrement du code. Juste pur, expressif, pythonic Zen.
Cette solution vous permet d'avoir une liste personnalisée de
exts
qui peut être changé sans avoir à mettre à jour votre code. (Ce qui est toujours une bonne pratique!)La liste-la compréhension est la même que celle utilisée dans Laurent solution (que j'ai voté pour). Mais je dirais qu'il est généralement inutile de factoriser une seule ligne à une fonction distincte, qui est pourquoi je suis de fournir cela comme une solution alternative.
Bonus:
Si vous avez besoin d'une recherche non seulement d'un seul répertoire, mais également tous les sous-répertoires, vous pouvez passer
recursive=True
et utiliser le multi-répertoire glob symbole**
1:Cela invoquer
glob.glob('<project_dir>/**/*.txt', recursive=True)
et ainsi de suite pour chaque extension.1 Techniquement, le
**
glob symbole simplement correspond à un ou plusieurs caractères y compris la barre oblique/
(contrairement au singulier*
glob symbole). Dans la pratique, vous avez juste besoin de se rappeler que, tant que vous entourent**
avec des barres obliques (séparateurs de chemin), il correspond à zéro ou plusieurs répertoires.J'ai publié Formique qui met en œuvre de multiples comprend une manière similaire à Apache Ant FileSet et les Globules.
La recherche peut être mis en œuvre:
Parce que le plein Ant glob est mis en œuvre, vous pouvez inclure des répertoires différents avec chaque modèle, de sorte que vous pourriez choisir seulement ceux .les fichiers txt dans un sous-répertoire, et le .markdown dans un autre, par exemple:
J'espère que cette aide.
Pas
glob
, mais voici une autre façon à l'aide d'une compréhension de liste:La fonction suivante
_glob
globs pour plusieurs extensions de fichier.À
glob
plusieurs types de fichiers, vous devez appelerglob()
fonction plusieurs fois dans une boucle. Puisque cette fonction renvoie une liste, vous avez besoin de concaténer les listes.Par exemple, cette fonction de faire le travail:
Simple d'utilisation:
Vous pouvez également utiliser
glob.iglob()
avoir un itérateur:Vous pouvez essayer de faire un manuel liste de comparer l'extension de l'existant avec ceux dont vous avez besoin.
Vous pouvez utiliser le filtre:
Vous pouvez également utiliser
reduce()
comme suit:cela crée une liste à partir de
glob.glob()
pour chaque modèle et les réduit à une seule liste.https://docs.python.org/3.5/library/functools.html#functools.reduce
https://docs.python.org/3.5/library/operator.html#operator.add
Un glob, de nombreuses extensions... mais la solution imparfaite (peut correspondre à d'autres fichiers).
J'ai eu le même problème et c'est ce que je suis venu avec
Par exemple:
Une fonction:
Utiliser une liste d'extension et de parcourir
Encore une autre solution (utilisation
glob
pour obtenir des tracés à l'aide de multiples matchpatterns
et de combiner tous les chemins dans une seule liste à l'aide dereduce
etadd
):Si vous utilisez
pathlib
essayez ceci:Par les résultats que j'ai obtenus à partir de tests empiriques, il s'est avéré que
glob.glob
n'est pas la meilleure façon de filtrer les fichiers par leur extension. Certaines des raisons sont les suivantes:J'ai testé (pour correcteness et de l'efficacité dans le temps) à l'issue de
4
différentes méthodes pour filtrer les fichiers par les extensions et les met dans unelist
:En exécutant le code ci-dessus sur mon ordinateur portable que j'ai obtenus à la suite de l'auto-explicatifs des résultats.
Le moyen le plus rapide pour filtrer les fichiers par les extensions, arrive même à être le plus laid qu'un. Qui est, imbriqués
for
boucles etstring
comparaison à l'aide de laendswith()
méthode.En outre, comme vous pouvez le voir, l'expansion des algorithmes (avec le modèle
E:\x\y\z\**/*[py][pyc]
), même avec seulement2
extension donnée (py
etpyc
) renvoie également à des résultats incorrects.Cela Devrait Fonctionner:
cela a fonctionné pour moi:
or
opérateur renvoie le premier "non-falsy" de la valeur, donc dans votre cas:*.JPG
. Cela transforme votre appel englob.glob('*.JPG')
en ce sens qu'elle ne retourne que les*.JPG
fichiers, l'oublier totalement les autres extensions.