web-dev-qa-db-fra.com

Lecture de fichiers dans un ordre particulier en python

Disons que j'ai trois fichiers dans un dossier: file9.txt, file10.txt et file11.txt et que je veux les lire dans cet ordre particulier. Est-ce que quelqu'un peut m'aider avec ça?

En ce moment j'utilise le code 

import glob, os
for infile in glob.glob(os.path.join( '*.txt')):
    print "Current File Being Processed is: " + infile

et il lit d'abord fichier10.txt puis fichier11.txt et ensuite fichier9.txt.

Quelqu'un peut-il m'aider à obtenir le bon ordre?

27
user1620012

Les fichiers du système de fichiers ne sont pas triés. Vous pouvez trier vous-même les noms de fichiers obtenus à l’aide de la fonction sorted() :

for infile in sorted(glob.glob('*.txt')):
    print "Current File Being Processed is: " + infile

Notez que l'appel os.path.join dans votre code est un no-op; avec un seul argument, il ne fait rien mais renvoie cet argument non modifié.

Notez que vos fichiers seront triés par ordre alphabétique, ce qui place 10 avant 9. Vous pouvez utiliser une fonction de clé personnalisée pour améliorer le tri:

import re
numbers = re.compile(r'(\d+)')
def numericalSort(value):
    parts = numbers.split(value)
    parts[1::2] = map(int, parts[1::2])
    return parts

 for infile in sorted(glob.glob('*.txt'), key=numericalSort):
    print "Current File Being Processed is: " + infile

La fonction numericalSort divise les chiffres d'un nom de fichier, le convertit en un nombre réel et renvoie le résultat pour le tri:

>>> files = ['file9.txt', 'file10.txt', 'file11.txt', '32foo9.txt', '32foo10.txt']
>>> sorted(files)
['32foo10.txt', '32foo9.txt', 'file10.txt', 'file11.txt', 'file9.txt']
>>> sorted(files, key=numericalSort)
['32foo9.txt', '32foo10.txt', 'file9.txt', 'file10.txt', 'file11.txt']
56
Martijn Pieters

Vous pouvez envelopper votre expression glob.glob( ... ) dans une instruction sorted( ... ) et trier la liste de fichiers résultante. Exemple:

for infile in sorted(glob.glob('*.txt')):

Vous pouvez donner à sorted une fonction de comparaison ou, mieux, utiliser l'argument key= ... pour lui attribuer une clé personnalisée utilisée pour le tri.

Exemple:

Il y a les fichiers suivants:

x/blub01.txt
x/blub02.txt
x/blub10.txt
x/blub03.txt
y/blub05.txt

Le code suivant produira la sortie suivante:

for filename in sorted(glob.glob('[xy]/*.txt')):
        print filename
# x/blub01.txt
# x/blub02.txt
# x/blub03.txt
# x/blub10.txt
# y/blub05.txt

Maintenant avec fonction clé:

def key_func(x):
        return os.path.split(x)[-1]
for filename in sorted(glob.glob('[xy]/*.txt'), key=key_func):
        print filename
# x/blub01.txt
# x/blub02.txt
# x/blub03.txt
# y/blub05.txt
# x/blub10.txt

EDIT: Cette touche peut éventuellement trier vos fichiers:

pat=re.compile("(\d+)\D*$")
...
def key_func(x):
        mat=pat.search(os.path.split(x)[-1]) # match last group of digits
        if mat is None:
            return x
        return "{:>10}".format(mat.group(1)) # right align to 10 digits.

Cela peut certainement être amélioré, mais je pense que vous avez compris. Les chemins sans numéros seront laissés seuls, les chemins avec des nombres seront convertis en une chaîne large de 10 chiffres et contenant le nombre.

8
hochl
glob.glob(os.path.join( '*.txt'))

retourne une liste de chaînes, vous pouvez donc facilement trier la liste en utilisant la fonction python sort () .

sorted(glob.glob(os.path.join( '*.txt')))
0
apparat

Vous devez changer le tri de 'ASCIIBetical' en numérique en isolant le nombre dans le nom du fichier. Vous pouvez faire ça comme ça:

import re

def keyFunc(afilename):
    nondigits = re.compile("\D")
    return int(nondigits.sub("", afilename))

filenames = ["file10.txt", "file11.txt", "file9.txt"]

for x in sorted(filenames, key=keyFunc):
   print xcode here

Où vous pouvez définir des noms de fichiers avec le résultat de glob.glob ("*. Txt");

De plus, la fonction keyFunc suppose que le nom du fichier contiendra un numéro et que ce numéro ne figure que dans le nom du fichier. Vous pouvez modifier cette fonction pour qu'elle soit aussi complexe que nécessaire pour isoler le nombre sur lequel vous devez trier.

0
grieve