web-dev-qa-db-fra.com

Trier les noms de fichiers dans le répertoire par ordre croissant

J'ai un répertoire avec jpgs et d'autres fichiers, les jpgs ont tous des noms de fichiers avec des numéros. Certains peuvent avoir des chaînes supplémentaires dans le nom de fichier.

Par exemple.

01.jpg

Ou ça pourrait être

Picture 03.jpg

En Python j'ai besoin d'une liste de tous les jpgs dans l'ordre croissant. Voici l'extrait de code pour cela

import os
import numpy as np

myimages = [] #list of image filenames
dirFiles = os.listdir('.') #list of directory files
dirFiles.sort() #good initial sort but doesnt sort numerically very well
sorted(dirFiles) #sort numerically in ascending order

for files in dirFiles: #filter out all non jpgs
    if '.jpg' in files:
        myimages.append(files)
print len(myimages)
print myimages

Ce que je reçois est ceci

['0.jpg', '1.jpg', '10.jpg', '11.jpg', '12.jpg', '13.jpg', '14.jpg',
 '15.jpg', '16.jpg', '17.jpg', '18.jpg', '19.jpg', '2.jpg', '20.jpg',
 '21.jpg', '22.jpg', '23.jpg', '24.jpg', '25.jpg', '26.jpg', '27.jpg',
 '28.jpg', '29.jpg', '3.jpg', '30.jpg', '31.jpg', '32.jpg', '33.jpg',
 '34.jpg', '35.jpg', '36.jpg', '37.jpg', '4.jpg', '5.jpg', '6.jpg',
 '7.jpg', '8.jpg', '9.jpg']

De toute évidence, il trie aveuglément le nombre le plus significatif en premier. J'ai essayé d'utiliser sorted() comme vous pouvez le voir en espérant que cela le corrigerait mais cela ne fait aucune différence.

18
user3474042

En supposant qu'il n'y a qu'un seul numéro dans chaque nom de fichier:

>>> dirFiles = ['Picture 03.jpg', '02.jpg', '1.jpg']
>>> dirFiles.sort(key=lambda f: int(filter(str.isdigit, f)))
>>> dirFiles
['1.jpg', '02.jpg', 'Picture 03.jpg']
31
Stefan Pochmann

il y a un module natsort. Faites simplement pip install natsort.

>>> import natsort 
>>> ll = ['Picture 13.jpg', 'Picture 14.jpg', 'Picture 15.jpg','Picture 0.jpg', 'Picture 1.jpg', 'Picture 10.jpg', 'Picture 11.jpg', 'Picture 12.jpg',  'Picture 16.jpg', 'Picture 17.jpg', 'Picture 18.jpg', 'Picture 19.jpg', 'Picture 2.jpg', 'Picture 20.jpg', 'Picture 21.jpg', 'Picture 22.jpg', 'Picture 23.jpg', 'Picture 24.jpg', 'Picture 25.jpg', 'Picture 26.jpg', 'Picture 27.jpg', 'Picture 28.jpg', 'Picture 29.jpg', 'Picture 3.jpg', 'Picture 30.jpg', 'Picture 31.jpg', 'Picture 32.jpg', 'Picture 33.jpg', 'Picture 34.jpg', 'Picture 35.jpg', 'Picture 36.jpg', 'Picture 37.jpg']         
>>> print(natsort.natsorted(ll,reverse=True))
['Picture 37.jpg', 'Picture 36.jpg', 'Picture 35.jpg', 'Picture 34.jpg', 'Picture 33.jpg', 'Picture 32.jpg', 'Picture 31.jpg', 'Picture 30.jpg', 'Picture 29.jpg', 'Picture 28.jpg', 'Picture 27.jpg', 'Picture 26.jpg', 'Picture 25.jpg', 'Picture 24.jpg', 'Picture 23.jpg', 'Picture 22.jpg', 'Picture 21.jpg', 'Picture 20.jpg', 'Picture 19.jpg', 'Picture 18.jpg', 'Picture 17.jpg', 'Picture 16.jpg', 'Picture 15.jpg', 'Picture 14.jpg', 'Picture 13.jpg', 'Picture 12.jpg', 'Picture 11.jpg', 'Picture 10.jpg', 'Picture 3.jpg', 'Picture 2.jpg', 'Picture 1.jpg', 'Picture 0.jpg']
13
LetzerWille

J'ai un répertoire avec jpgs et d'autres fichiers.

[...]

['0.jpg', '1.jpg', '10 .jpg ', '11 .jpg', '12 .jpg ', '13 .jpg', '14 .jpg ', '15 .jpg', ' 16.jpg ', '17 .jpg', '18 .jpg ', '19 .jpg', '2.jpg', '20 .jpg ', '21 .jpg', '22 .jpg ', '23. jpg ', '24 .jpg', '25 .jpg ', '26 .jpg', '27 .jpg ', '28 .jpg', '29 .jpg ',' 3.jpg ', '30 .jpg' , '31 .jpg ', '32 .jpg', '33 .jpg ', '34 .jpg', '35 .jpg ', '36 .jpg', '37 .jpg ',' 4.jpg ',' 5.jpg ',' 6.jpg ',' 7.jpg ',' 8.jpg ',' 9.jpg '] Clairement, il trie aveuglément le nombre le plus significatif en premier. J'ai essayé d'utiliser sorted () comme vous pouvez le voir en espérant que cela le corrigerait mais cela ne fait aucune différence

Vous pouvez utiliser splitext pour obtenir la pièce sans l'extension et la convertir en int pour le tri. Si la liste est nommée 'l' et la liste triée est nommée 'lsorted', vous pouvez utiliser:

lsorted = sorted(l,key=lambda x: int(os.path.splitext(x)[0]))

os.path.splitext sur '10 .jpg 'renvoie [' 10 ','. jpg '] donc prendre l'int () de l'élément zéro vous donnera ce que vous voulez tant que les noms de fichiers sans l'extension ne contiennent que des chaînes qui peuvent être converti en entiers avec int (). Sinon, vous rencontrerez une erreur.

5
hft