J'utilise souvent python pour traiter des répertoires de données. Récemment, j'ai remarqué que l'ordre par défaut des listes a changé pour quelque chose de presque absurde. Par exemple, si je suis dans un répertoire courant contenant les sous-répertoires suivants: run01, run02, ... run19, run20, puis je génère une liste à partir de la commande suivante:
dir = os.listdir(os.getcwd())
alors j'obtiens généralement une liste dans cet ordre:
dir = ['run01', 'run18', 'run14', 'run13', 'run12', 'run11', 'run08', ... ]
etc. L'ordre était alphanumérique. Mais ce nouvel ordre m'est resté depuis un moment maintenant.
Qu'est-ce qui détermine l'ordre (affiché) de ces listes?
python
list
directory-listing
listdir
marshall.ward
la source
la source
listdir
sortie triée . Je ne sais pas pourquoi les questions ont été fusionnées.Réponses:
Je pense que la commande a à voir avec la façon dont les fichiers sont indexés sur votre FileSystem. Si vous voulez vraiment le faire adhérer à un ordre, vous pouvez toujours trier la liste après avoir récupéré les fichiers.
la source
Vous pouvez utiliser la
sorted
fonction intégrée pour trier les chaînes comme vous le souhaitez. Sur la base de ce que vous décrivez,Vous pouvez également utiliser la
.sort
méthode d'une liste:Je pense que ça devrait faire l'affaire.
Notez que l'ordre dans lequel
os.listdir
les noms de fichiers sont obtenus dépend probablement complètement de votre système de fichiers.la source
sorted(listdir)
travaillé pour moi.listdir.sort()
m'a donné: TypeError: l'objet 'NoneType' n'est pas itérablereverse=True
pour faire un tri décroissant.sorted
chose écrite en premier le fait en une seule ligne OK?Selon la documentation :
L'ordre ne peut être invoqué et est un artefact du système de fichiers.
Pour trier le résultat, utilisez
sorted(os.listdir(path))
.la source
Python pour une raison quelconque ne vient pas avec un moyen intégré d'avoir un tri naturel (ce qui signifie 1, 2, 10 au lieu de 1, 10, 2), vous devez donc l'écrire vous-même:
Vous pouvez maintenant utiliser cette fonction pour trier une liste:
PROBLÈMES: Si vous utilisez la fonction ci-dessus pour trier les chaînes (par exemple les noms de dossier) et que vous voulez les trier comme le fait l'Explorateur Windows, cela ne fonctionnera pas correctement dans certains cas extrêmes.
Cette fonction de tri renverra des résultats incorrects sous Windows, si vous avez des noms de dossier contenant certains caractères «spéciaux». Par exemple, cette fonction triera
1, !1, !a, a
, alors que l'Explorateur Windows triera!1, 1, !a, a
.Donc, si vous voulez trier exactement comme l'explorateur Windows le fait en Python, vous devez utiliser la fonction intégrée de Windows StrCmpLogicalW via ctypes (cela ne fonctionnera bien sûr pas sous Unix):
Cette fonction est légèrement plus lente que
sorted_alphanumeric()
.Bonus:
winsort
peut également trier les chemins complets sous Windows .Alternativement, surtout si vous utilisez Unix, vous pouvez utiliser la
natsort
bibliothèque (pip install natsort
) pour trier par chemins complets d'une manière correcte (c'est-à-dire les sous-dossiers à la bonne position).Vous pouvez l'utiliser comme ceci pour trier les chemins complets:
Ne l'utilisez pas pour le tri normal des noms de dossiers (ou des chaînes en général), car c'est un peu plus lent que la
sorted_alphanumeric()
fonction ci-dessus.natsorted
La bibliothèque vous donnera des résultats incorrects si vous vous attendez à un tri dans l'Explorateur Windows, alors utilisez-lewinsort()
pour cela.la source
print( sorted_aphanumeric(["1", "10", "2", "foo_10", "foo_8"]) )
->['1', '2', '10', 'foo_8', 'foo_10']
. Exactement comme prévu.natsorted
pour la mise en œuvre de la fonctionnalité de correspondance de l'Explorateur Windows. Peut-être devriez-vous apporter une solution? github.com/SethMMorton/natsort/issues/41Je pense que par défaut, l'ordre est déterminé avec la valeur ASCII. La solution à ce problème est la suivante
la source
C'est probablement juste l'ordre que
readdir()
retourne C. Essayez d'exécuter ce programme C:La ligne de construction devrait être quelque chose comme
gcc -o foo foo.c
.PS J'ai juste exécuté ceci et votre code Python, et ils m'ont tous les deux donné une sortie triée, donc je ne peux pas reproduire ce que vous voyez.
la source
Comme dans le cas de mes besoins, j'ai le cas comme
row_163.pkl
ici,os.path.splitext('row_163.pkl')
je vais le diviser en('row_163', '.pkl')
donc je dois le diviser en fonction de '_' également.mais en cas de besoin, vous pouvez faire quelque chose comme
où
et aussi pour la récupération de répertoire, vous pouvez faire
sorted(os.listdir(path))
et pour le cas
'run01.txt'
ou'run01.csv'
vous pouvez faire comme çala source
J'ai trouvé que le «tri» ne faisait pas toujours ce que j'attendais. par exemple, j'ai un répertoire comme ci-dessous, et le "tri" me donne un résultat très étrange:
Il semble qu'il compare le premier personnage en premier, si c'est le plus gros, ce serait le dernier.
la source
('5' > '403') is True
.De la documentation :
Cela signifie que l'ordre dépend probablement du système d'exploitation / du système de fichiers, n'a pas d'ordre particulièrement significatif et n'est donc pas garanti d'être quelque chose de particulier. Autant de réponses mentionnées: si vous préférez, la liste récupérée peut être triée.
À votre santé :)
la source
La réponse d'Elliot le résout parfaitement mais parce que c'est un commentaire, cela passe inaperçu donc dans le but d'aider quelqu'un, je le réitère comme une solution.
Utilisez la bibliothèque natsort:
Installez la bibliothèque avec la commande suivante pour Ubuntu et d'autres versions de Debian
Python 2
Python 3
Les détails de l'utilisation de cette bibliothèque se trouve ici
la source
sorted()
! MerciLa combinaison proposée des commandes
os.listdir
etsorted
génère le même résultat que lals -l
commande sous Linux. L'exemple suivant vérifie cette hypothèse:Donc, pour quelqu'un qui veut reproduire le résultat de la
ls -l
commande bien connue dans son code python, celasorted( os.listdir( DIR ) )
fonctionne plutôt bien.la source
la source