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?
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']
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.
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')))
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.