Pythons glob.glob nasıl sipariş edilir?


200

Aşağıdaki Python kodunu yazdım:

#!/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

Şimdi anladım:

/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

Hangi yolla sipariş ediliyor?

Benim ls -l çıktımı almanıza yardımcı olabilir:

-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

Dosya adı veya boyuta göre sıralanmamıştır.

Diğer bağlantılar: glob,ls


2
Son cevap, lskomutun kendisinin dosyaları ada göre sıralaması gibi görünüyor . 'ls -U', "dizin sırası" ndaki dosyaların sırasız bir listesini verir.
Brian Peterson

2
Windows üzerinde bu yüzden sadece her zaman öyle olduğunu kabul böylece sıralanmış ... şimdi Ubuntu bana hata ayıklama maliyeti. Kendi kendine not - api okuyun! : 0)
Yuri Feldman

Davranış ile aynıdır os.listdir: * nix OS, dosyaları alfabetik olmayan bir sırayla döndürür ve (beni şaşırtacak!) Bu belgelerde açıktır : "Liste keyfi sıradadır".
Joël

Yanıtlar:


112

Muhtemelen hiç sıralanmamıştır ve dosya sisteminde girişlerin göründüğü sırayı, yani kullanırken aldığınız sırayı kullanır ls -U. (En azından makinemde bu, listeleme globeşleşmeleriyle aynı siparişi verir ).


1
Evet, özel bir çaba göstermedikçe, girişleri işletim sistemi sağladığı gibi gösterecektir. Unix'teki "find" komutuyla aynı, girişleri temeldeki dosya sistemi tarafından kullanılan veri yapısından geldikleri sırayla dökümler. Dosyaların oluşturma sırasında göründüğünü görseniz bile, siparişiyle ilgili herhangi bir varsayımda bulunmamalısınız.
Raúl Salinas-Monteagudo

424

Düzen isteğe bağlıdır, ancak bunları kendiniz sıralayabilirsiniz

Ada göre sıralamak istiyorsanız:

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

değişiklik zamanına göre sıralanmıştır:

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

boyuta göre sıralı:

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

vb.


1
Kullandığım yüzden uzantısı olmadan, isimler sadece tam sayılar dosyaları vardır: files = glob.glob('teksty/*'). İsimle verilen sipariş verilecek mi?
andilabs

3
@mgalgs Hayır, gerçekten sormak istediğim soru bu değildi. Bilmek istediklerim Xion tarafından cevaplandı.
Martin Thoma

Ve yaratılış tarihine göre ama yaratılış zamanına göre sıralamaya ne dersiniz? Çünkü önce en yeni dosyaları listeliyor. Eski listeden en yeni dosyalara nasıl bir liste alabilirim? Teşekkür ederim!
joaquindev

1
Getmtime ve getsize nispeten pahalı olduğunu unutmayın - bir sürü dosya için bunu yapmak biraz zaman alabilir ..
drevicko

53

Kaynak kodunu kontrol ederek glob.globdahili olarak aradığını os.listdirve burada açıklandığını görürsünüz :

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

Anahtar cümle: os.listdir (yol) Dizin, yol tarafından verilen girişlerin adlarını içeren bir liste döndürür. Liste keyfi sıradadır. '.' Özel girişlerini içermez. ve '..' dizinde bulunsalar bile.

Keyfi düzen . :)


14

glob.glob (), os.listdir () etrafında bir sargıdır, bu nedenle altta yatan işletim sistemi verileri iletmekten sorumludur. Genel olarak: burada sipariş hakkında bir varsayım yapamazsınız. Temel varsayım: sipariş yok . Bazı sıralamalara ihtiyacınız varsa: uygulama düzeyinde sıralayın.


13

Düzen isteğe bağlıdır, ancak bunları sıralamanın birkaç yolu vardır. Bunlardan biri şöyledir:

#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]))

Cevabınız mevcut cevaplara kıyasla ne katıyor?
Martin Thoma

2
@MartinThoma Dosyalarda bulunan tamsayılar sıfır dolgulu değilse, dosya adlarını sıralamamakla ilgili bir sorunum var. Sıralama 1000'de başlar, en yüksek tam sayı olana kadar gider ve sonra en küçük tam sayıdan başlar. Numaraları sıfırlarsam, dosyalar üzerinde sıralanmış olarak çağırmak onları mükemmel bir şekilde sıralar. Bu yüzden, bu çözüm tek başına sıralanmadığında sorunu çözdüğünü düşünüyorum
Will.Evo

1
@ Will.Evo kullanmayı deneyin natsort: from natsort import natsorted; files = natsorted(files).
Martin Thoma

Cevabınız yardımcı oldu!
Vine

12

Benzer bir sorun vardı, globrasgele sırada dosya adlarının bir listesini döndürüyordu ama dosya adıyla belirtildiği gibi sayısal sırayla onları adım atmak istedim. Bunu nasıl başardım:

Dosyalarım aşağıdaki globgibi bir şey tarafından döndürüldü :

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"]

Listeyi yerinde sıraladım, bunu yapmak için bir işlev oluşturdum:

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

Bu işlev, dosya adının sayısal kısmını döndürür ve bir tamsayıya dönüştürür. Daha sonra listede sıralama yöntemi olarak adlandırılır:

myList.sort(key=sortKeyFunc)

Bu, aşağıdaki gibi bir liste döndürdü:

["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"]

Bence os.path.splitext(os.path.basename(s))[0]yerine kullanmak daha zarif os.path.basename(s)[:-4], bu yüzden işlev tanımı olacak. def sortKeyFunc(s): return int(os.path.splitext(os.path.basename(s))[0])
ePandit

1

Geçmişte glob.glob'un sisteminizde ne yaptığını merak ediyorsanız ve sortedçağrı ekleyemiyorsanız , sipariş Mac HFS + dosya sistemlerinde tutarlı olacak ve diğer Unix sistemlerinde geçiş sırası olacaktır . Dolayısıyla, altta yatan dosya sistemi yeniden düzenlenmedikçe, dosyalar eklenir, kaldırılır, yeniden adlandırılır, silinir, taşınır vb.


MacOS'ta APFS ne olacak?
Boris

1

@Johan La Rooy'un çözümünden, görüntüleri kullanarak sıralamak sorted(glob.glob('*.png'))benim için işe yaramıyor, çıktı listesi hala isimlerine göre sıralanmıyor.

Ancak, sorted(glob.glob('*.png'), key=os.path.getmtime)mükemmel çalışır.

İsimlerine göre sıralama burada işe yaramıyor biraz karışık.

Bu harika soruyu paylaştığı için @Martin Thoma'ya ve faydalı çözümler için @Johan La Rooy'a teşekkür ederiz.


-1

Lütfen bu kodu deneyin:

sorted(glob.glob( os.path.join(path, '*.png') ),key=lambda x:float(re.findall("([0-9]+?)\.png",x)[0]))

-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])

Özel durumumu böyle yaptım. Umarım faydalıdır.


1
Cevabınızı soruya uyacak şekilde değiştirmelisiniz.
CodenameLambda

1
Soru sıralama ile ilgili değildir. Nasıl sıralanacağını biliyorum (ve o zamanlar biliyordum). Soru, varsayılan siparişle ilgilidir.
Martin Thoma

1
Anında yardım sağlayabilecek bu kod snippet'i için teşekkür ederiz. Uygun bir açıklama göstererek eğitim değerini büyük ölçüde artıracaktır . neden problem için iyi bir çözüm olduğunu benzer, ancak aynı olmayan soruları olan gelecekteki okuyucular için daha yararlı hale getirecektir. Lütfen açıklama eklemek için cevabınızı düzenleyin ve hangi sınırlamaların ve varsayımların geçerli olduğunu belirtin.
Toby Speight
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.