Często używam Pythona do przetwarzania katalogów danych. Ostatnio zauważyłem, że domyślna kolejność list zmieniła się na coś prawie bezsensownego. Na przykład, jeśli jestem w bieżącym katalogu zawierającym następujące podkatalogi: run01, run02, ... run19, run20, a następnie generuję listę za pomocą następującego polecenia:
dir = os.listdir(os.getcwd())
wtedy zwykle otrzymuję listę w następującej kolejności:
dir = ['run01', 'run18', 'run14', 'run13', 'run12', 'run11', 'run08', ... ]
i tak dalej. Porządek był alfanumeryczny. Ale ten nowy porządek pozostał we mnie już od jakiegoś czasu.
Co decyduje o (wyświetlanej) kolejności tych list?
python
list
directory-listing
listdir
marshall.ward
źródło
źródło
listdir
wyniki. Nie jestem pewien, dlaczego pytania zostały połączone.Odpowiedzi:
Myślę, że kolejność ma związek ze sposobem indeksowania plików w systemie plików. Jeśli naprawdę chcesz, aby zachowała się w jakiejś kolejności, zawsze możesz posortować listę po pobraniu plików.
źródło
Możesz użyć wbudowanej
sorted
funkcji do sortowania łańcuchów w dowolny sposób. Na podstawie tego, co opisujesz,Alternatywnie możesz użyć
.sort
metody listy:Myślę, że powinienem załatwić sprawę.
Zwróć uwagę, że kolejność
os.listdir
pobierania nazw plików jest prawdopodobnie całkowicie zależna od twojego systemu plików.źródło
sorted(listdir)
Pracował tylko dla mnie.listdir.sort()
dał mi: TypeError: Obiekt 'NoneType' nie jestreverse=True
aby posortować malejąco.sorted
rzecz napisana jako pierwsza, czy to w jednej linii OK?Zgodnie z dokumentacją :
Nie można polegać na porządku i jest on artefaktem systemu plików.
Aby posortować wynik, użyj
sorted(os.listdir(path))
.źródło
Z jakiegoś powodu Python nie ma wbudowanego sposobu na naturalne sortowanie (czyli 1, 2, 10 zamiast 1, 10, 2), więc musisz napisać to sam:
Możesz teraz użyć tej funkcji do sortowania listy:
PROBLEMY: Jeśli użyjesz powyższej funkcji do sortowania ciągów (na przykład nazw folderów) i chcesz, aby były posortowane tak, jak robi to Eksplorator Windows, nie będzie ona działać poprawnie w niektórych skrajnych przypadkach.
Ta funkcja sortowania zwróci nieprawidłowe wyniki w systemie Windows, jeśli masz nazwy folderów z określonymi znakami „specjalnymi”. Na przykład ta funkcja posortuje
1, !1, !a, a
, podczas gdy Eksplorator Windows posortuje!1, 1, !a, a
.Więc jeśli chcesz sortować dokładnie tak, jak robi to Eksplorator Windows w Pythonie , musisz użyć wbudowanej funkcji Windows StrCmpLogicalW poprzez ctypes (to oczywiście nie zadziała na Uniksie):
Ta funkcja jest nieco wolniejsza niż
sorted_alphanumeric()
.Bonus:
winsort
można również sortować pełne ścieżki w systemie Windows .Alternatywnie, zwłaszcza jeśli używasz Uniksa, możesz użyć
natsort
biblioteki (pip install natsort
) do sortowania według pełnych ścieżek w prawidłowy sposób (co oznacza podfoldery we właściwej pozycji).Możesz go użyć w ten sposób do sortowania pełnych ścieżek:
Nie używaj go do normalnego sortowania tylko nazw folderów (lub ogólnie ciągów znaków), ponieważ jest to nieco wolniejsze niż
sorted_alphanumeric()
funkcja powyżej.natsorted
biblioteka da nieprawidłowe wyniki, jeśli spodziewasz się sortowania w Eksploratorze Windows, więc użyjwinsort()
do tego.źródło
print( sorted_aphanumeric(["1", "10", "2", "foo_10", "foo_8"]) )
->['1', '2', '10', 'foo_8', 'foo_10']
. Dokładnie tak, jak oczekiwano.natsorted
zaimplementowaniem funkcji dopasowywania Eksploratora Windows. Może powinieneś wnieść rozwiązanie? github.com/SethMMorton/natsort/issues/41Myślę, że domyślnie kolejność jest określana za pomocą wartości ASCII. Rozwiązanie tego problemu jest następujące
źródło
Prawdopodobnie jest to tylko kolejność, z której
readdir()
zwraca C. Spróbuj uruchomić ten program w C:Linia budowania powinna być podobna
gcc -o foo foo.c
.PS Właśnie uruchomiłem to i twój kod w Pythonie i oba dały mi posortowane dane wyjściowe, więc nie mogę odtworzyć tego, co widzisz.
źródło
Ponieważ w przypadku mojego wymagania mam przypadek taki jak
row_163.pkl
tutajos.path.splitext('row_163.pkl')
,('row_163', '.pkl')
więc podzielę go również na podstawie '_'.ale w przypadku twojego wymagania możesz zrobić coś takiego
gdzie
a także do pobierania katalogów, które możesz zrobić
sorted(os.listdir(path))
a na wypadek jak
'run01.txt'
lub'run01.csv'
możesz to zrobićźródło
Odkryłem, że „sort” nie zawsze robi to, czego się spodziewałem. np. mam katalog jak poniżej, a "sort" daje mi bardzo dziwny wynik:
Wygląda na to, że najpierw porównuje pierwszą postać, jeśli to jest największa, to będzie ostatnia.
źródło
('5' > '403') is True
.Z dokumentacji :
Oznacza to, że kolejność jest prawdopodobnie zależna od systemu operacyjnego / systemu plików, nie ma szczególnie znaczącej kolejności i dlatego nie gwarantuje się, że będzie to coś szczególnego. Jak wspomniano w wielu odpowiedziach: jeśli jest to preferowane, pobrana lista może być sortowana.
Twoje zdrowie :)
źródło
Odpowiedź Elliota rozwiązuje to doskonale, ale ponieważ jest to komentarz, pozostaje niezauważony, więc aby komuś pomóc, powtarzam to jako rozwiązanie.
Użyj biblioteki natsort:
Zainstaluj bibliotekę za pomocą następującego polecenia dla Ubuntu i innych wersji Debiana
Python 2
Python 3
Szczegóły dotyczące korzystania z tej biblioteki można znaleźć tutaj
źródło
sorted()
! DziękiProponowana kombinacja poleceń
os.listdir
isorted
daje taki sam wynik jakls -l
polecenie w systemie Linux. Poniższy przykład weryfikuje to założenie:Tak więc, dla kogoś, kto chce odtworzyć wynik dobrze znanego
ls -l
polecenia w swoim kodzie Pythona,sorted( os.listdir( DIR ) )
działa całkiem dobrze.źródło
źródło