Jak zamawia się Pythons glob.glob?

199

Napisałem następujący kod Python:

#!/usr/bin/python
# -*- coding: utf-8 -*-

import os, glob

path = '/home/my/path'
for infile in glob.glob( os.path.join(path, '*.png') ):
    print infile

Teraz rozumiem:

/home/my/path/output0352.png
/home/my/path/output0005.png
/home/my/path/output0137.png
/home/my/path/output0202.png
/home/my/path/output0023.png
/home/my/path/output0048.png
/home/my/path/output0069.png
/home/my/path/output0246.png
/home/my/path/output0071.png
/home/my/path/output0402.png
/home/my/path/output0230.png
/home/my/path/output0182.png
/home/my/path/output0121.png
/home/my/path/output0104.png
/home/my/path/output0219.png
/home/my/path/output0226.png
/home/my/path/output0215.png
/home/my/path/output0266.png
/home/my/path/output0347.png
/home/my/path/output0295.png
/home/my/path/output0131.png
/home/my/path/output0208.png
/home/my/path/output0194.png

W jaki sposób jest zamówiony?

Może ci pomóc uzyskać mój wynik ls -l:

-rw-r--r-- 1 moose moose 627669 2011-07-17 17:26 output0005.png
-rw-r--r-- 1 moose moose 596417 2011-07-17 17:26 output0023.png
-rw-r--r-- 1 moose moose 543639 2011-07-17 17:26 output0048.png
-rw-r--r-- 1 moose moose 535384 2011-07-17 17:27 output0069.png
-rw-r--r-- 1 moose moose 543216 2011-07-17 17:27 output0071.png
-rw-r--r-- 1 moose moose 561776 2011-07-17 17:27 output0104.png
-rw-r--r-- 1 moose moose 501865 2011-07-17 17:27 output0121.png
-rw-r--r-- 1 moose moose 547144 2011-07-17 17:27 output0131.png
-rw-r--r-- 1 moose moose 530596 2011-07-17 17:27 output0137.png
-rw-r--r-- 1 moose moose 532567 2011-07-17 17:27 output0182.png
-rw-r--r-- 1 moose moose 553562 2011-07-17 17:27 output0194.png
-rw-r--r-- 1 moose moose 574065 2011-07-17 17:27 output0202.png
-rw-r--r-- 1 moose moose 552197 2011-07-17 17:27 output0208.png
-rw-r--r-- 1 moose moose 559809 2011-07-17 17:27 output0215.png
-rw-r--r-- 1 moose moose 549046 2011-07-17 17:27 output0219.png
-rw-r--r-- 1 moose moose 566661 2011-07-17 17:27 output0226.png
-rw-r--r-- 1 moose moose 561678 2011-07-17 17:27 output0246.png
-rw-r--r-- 1 moose moose 525550 2011-07-17 17:27 output0266.png
-rw-r--r-- 1 moose moose 565715 2011-07-17 17:27 output0295.png
-rw-r--r-- 1 moose moose 568381 2011-07-17 17:28 output0347.png
-rw-r--r-- 1 moose moose 532768 2011-07-17 17:28 output0352.png
-rw-r--r-- 1 moose moose 535818 2011-07-17 17:28 output0402.png

Nie jest uporządkowane według nazwy pliku ani rozmiaru.

Inne linki: glob,ls

Martin Thoma
źródło
2
Ostateczną odpowiedzią wydaje się być to, że lssamo polecenie sortuje pliki według nazw. „ls -U” daje nieuporządkowaną listę plików w „kolejności katalogów”.
Brian Peterson
2
W systemie Windows został posortowany, więc po prostu założyłem, że zawsze tak jest. Teraz w Ubuntu kosztowało mnie to debugowania. Uwaga do siebie - przeczytaj API! : 0)
Yuri Feldman
Zachowanie jest takie samo os.listdir: * nix OS zwraca pliki w całkiem nie alfabetycznej kolejności, i (wstyd mnie, żebym się zdziwił!) Jest to wyraźnie zaznaczone w dokumentacji : „Lista jest w dowolnej kolejności”.
Joël

Odpowiedzi:

112

Prawdopodobnie nie jest w ogóle posortowany i używa kolejności, w jakiej wpisy pojawiają się w systemie plików, tj. Tej, którą otrzymujesz podczas używania ls -U. (Przynajmniej na moim komputerze powoduje to taką samą kolejność, jak globdopasowanie do listy ).

Xion
źródło
1
Tak, chyba że dołoży specjalnego wysiłku, po prostu wyświetli wpisy, tak jak zapewnia to system operacyjny. To samo co polecenie „znajdź” w Uniksie, po prostu zrzuca wpisy w kolejności, w jakiej pochodzą ze struktury danych używanej przez bazowy system plików. Nie powinieneś przyjmować żadnych założeń dotyczących jego kolejności, nawet jeśli zobaczysz, że pliki wydają się pojawiać w kolejności tworzenia.
Raúl Salinas-Monteagudo
421

Porządek jest dowolny, ale możesz je posortować samodzielnie

Jeśli chcesz posortować według nazwy:

sorted(glob.glob('*.png'))

posortowane według czasu modyfikacji:

import os
sorted(glob.glob('*.png'), key=os.path.getmtime)

posortowane według rozmiaru:

import os
sorted(glob.glob('*.png'), key=os.path.getsize)

itp.

John La Rooy
źródło
1
Mam pliki, w których nazwy są tylko liczby całkowite, bez rozszerzenia, więc używam: files = glob.glob('teksty/*'). Czy zamówienie zostanie wydane przez nam?
andilabs
3
@mgalgs Nie, to nie było pytanie, które naprawdę chciałem zadać. Na to, co chciałem wiedzieć, odpowiedział Xion.
Martin Thoma,
A co z sortowaniem według daty utworzenia, ale według czasu utworzenia. Ponieważ wyświetla mi się jako pierwsza lista najnowszych plików. Jak mogę uzyskać listę plików od starych do najnowszych? Dziękuję Ci!
joaquindev
1
Pamiętaj, że getmtime i getize są stosunkowo drogie - zrobienie tego dla wielu plików może trochę potrwać ...
drevicko
53

Sprawdzając kod źródłowy glob.glob, widzisz, że wywołuje wewnętrznie os.listdir, opisane tutaj:

http://docs.python.org/library/os.html?highlight=os.listdir#os.listdir

Zdanie kluczowe: os.listdir (ścieżka) Zwraca listę zawierającą nazwy wpisów w katalogu podanych przez ścieżkę. Lista jest w dowolnej kolejności. Nie obejmuje wpisów specjalnych „”. i „..”, nawet jeśli są obecne w katalogu.

Arbitralny porządek . :)

Ray Toal
źródło
14

glob.glob () jest opakowaniem wokół os.listdir (), więc podkładanie systemu operacyjnego jest odpowiedzialne za dostarczanie danych. Ogólnie: tutaj nie można zakładać zamówienia. Podstawowym założeniem jest: brak zamawiania. Jeśli potrzebujesz sortowania: sortuj na poziomie aplikacji.

Andreas Jung
źródło
13

Porządek jest arbitralny, ale istnieje kilka sposobów ich sortowania. Jednym z nich jest:

#First, get the files:
import glob
import re
files =glob.glob1(img_folder,'*'+output_image_format)
# if you want sort files according to the digits included in the filename, you can do as following:
files = sorted(files, key=lambda x:float(re.findall("(\d+)",x)[0]))
kwiecień
źródło
Co wnosi Twoja odpowiedź w porównaniu do istniejących odpowiedzi?
Martin Thoma,
2
@MartinThoma Mam problem z sortowaniem braku sortowania nazw plików, jeśli liczby całkowite obecne w plikach nie są wypełnione zerami. Sortowanie rozpoczyna się od 1000, idzie w górę do najwyższej liczby całkowitej, a następnie zaczyna się od najmniejszej liczby całkowitej. Jeśli zeruję numery, po prostu wywołanie posortowane według plików posortuje je idealnie. Myślę więc, że to rozwiązanie rozwiązuje problem, gdy samo sortowanie nie działa.
Will.Evo
@ Will.Evo Spróbuj użyć natsort: from natsort import natsorted; files = natsorted(files).
Martin Thoma,
Twoja odpowiedź pomogła!
Vineet
12

Miałem podobny problem, globzwracałem listę nazw plików w dowolnej kolejności, ale chciałem je przeglądać w kolejności numerycznej, jak wskazuje nazwa pliku. Oto jak to osiągnąłem:

Moje pliki zostały zwrócone przez globcoś takiego:

myList = ["c:\tmp\x\123.csv", "c:\tmp\x\44.csv", "c:\tmp\x\101.csv", "c:\tmp\x\102.csv", "c:\tmp\x\12.csv"]

Posortowałem listę w miejscu, aby to zrobić, stworzyłem funkcję:

def sortKeyFunc(s):
    return int(os.path.basename(s)[:-4])

Ta funkcja zwraca część numeryczną nazwy pliku i konwertuje na liczbę całkowitą. Następnie wywołałem metodę sortowania na liście jako taką:

myList.sort(key=sortKeyFunc)

To zwróciło listę jako taką:

["c:\tmp\x\12.csv", "c:\tmp\x\44.csv", "c:\tmp\x\101.csv", "c:\tmp\x\102.csv", "c:\tmp\x\123.csv"]
Hornbydd
źródło
Myślę, że jest bardziej elegancki w użyciu os.path.splitext(os.path.basename(s))[0]zamiast os.path.basename(s)[:-4], więc definicja funkcji będzie. def sortKeyFunc(s): return int(os.path.splitext(os.path.basename(s))[0])
ePandit
1

Jeśli zastanawiasz się, co glob.glob zrobił w twoim systemie w przeszłości i nie możesz dodać sortedpołączenia, kolejność będzie spójna w systemach plików Mac HFS + i będzie kolejnością przechodzenia przez inne systemy uniksowe. Prawdopodobnie byłby deterministyczny, chyba że bazowy system plików został zreorganizowany, co może się zdarzyć, jeśli pliki zostaną dodane, usunięte, przemianowane, usunięte, przeniesione itp.

crizCraig
źródło
Co z APFS na macOS?
Boris
0

Według rozwiązania @Johan La Rooy sortowanie obrazów za pomocą sorted(glob.glob('*.png'))nie działa dla mnie, lista wyników wciąż nie jest uporządkowana według ich nazw.

Jednak sorted(glob.glob('*.png'), key=os.path.getmtime)działa idealnie.

Jestem trochę zdezorientowany, jak sortowanie według ich nazw nie działa tutaj.

Dziękuję @Martin Thoma za opublikowanie tego wspaniałego pytania i @Johan La Rooy za pomocne rozwiązania.

Haoyu Wang
źródło
-1

Spróbuj tego kodu:

sorted(glob.glob( os.path.join(path, '*.png') ),key=lambda x:float(re.findall("([0-9]+?)\.png",x)[0]))
faris
źródło
-3
'''my file name is 
"0_male_0.wav", "0_male_2.wav"... "0_male_30.wav"... 
"1_male_0.wav", "1_male_2.wav"... "1_male_30.wav"... 
"8_male_0.wav", "8_male_2.wav"... "8_male_30.wav"

when I wav.read(files) I want to read them in a sorted torder, i.e., "0_male_0.wav"
"0_male_1.wav"
"0_male_2.wav" ...
"0_male_30.wav"
"1_male_0.wav"
"1_male_1.wav"
"1_male_2.wav" ...
"1_male_30.wav"
so this is how I did it.

Just take all files start with "0_*" as an example. Others you can just put it in a loop
'''

import scipy.io.wavfile as wav
import glob 
from os.path import isfile, join

#get all the file names in file_names. THe order is totally messed up
file_names = [f for f in listdir(audio_folder_dir) if isfile(join(audio_folder_dir, f)) and '.wav' in f] 
#find files that belongs to "0_*" group
filegroup0 = glob.glob(audio_folder_dir+'/0_*')
#now you get sorted files in group '0_*' by the last number in the filename
filegroup0 = sorted(filegroup0, key=getKey)

def getKey(filename):
    file_text_name = os.path.splitext(os.path.basename(filename))  #you get the file's text name without extension
    file_last_num = os.path.basename(file_text_name[0]).split('_')  #you get three elements, the last one is the number. You want to sort it by this number
    return int(file_last_num[2])

Tak właśnie zrobiłem mój konkretny przypadek. Mam nadzieję, że to jest pomocne.

Elizabeth
źródło
1
Powinieneś zmienić swoją odpowiedź, aby pasowała do pytania.
CodenameLambda
1
Pytanie nie dotyczy sortowania. Wiem (i wtedy wiedziałem), jak sortować. Pytanie dotyczy domyślnej kolejności.
Martin Thoma,
1
Dziękujemy za ten fragment kodu, który może zapewnić natychmiastową pomoc. Właściwe wyjaśnienie znacznie poprawiłoby jego wartość edukacyjną, pokazując, dlaczego jest to dobre rozwiązanie problemu i uczyniłoby to bardziej użytecznym dla przyszłych czytelników z podobnymi, ale nie identycznymi pytaniami. Proszę edytować swoje odpowiedzi, aby dodać wyjaśnienie, i dać wskazówkę co zastosować ograniczenia i założenia.
Toby Speight