Pythons glob.glob สั่งซื้ออย่างไร


200

ฉันได้เขียนรหัสไพ ธ อนต่อไปนี้:

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

ตอนนี้ฉันได้รับสิ่งนี้:

/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

สั่งซื้อในทางใด?

มันอาจช่วยให้คุณรับ ls -l output ของฉัน:

-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

มันไม่ได้เรียงตามชื่อไฟล์หรือขนาด

ลิงค์อื่น ๆ : glob,ls


2
คำตอบสุดท้ายดูเหมือนว่าlsคำสั่งจะเรียงลำดับไฟล์ตามชื่อ 'ls -U' ให้รายการไฟล์ที่ไม่มีการเรียงลำดับใน "ลำดับไดเรกทอรี"
Brian Peterson

2
บน windows มันถูกเรียงลำดับดังนั้นฉันจึงสันนิษฐานว่ามันเป็นอย่างนั้นเสมอ .. ตอนนี้บน Ubuntu มันมีค่าใช้จ่ายในการดีบัก หมายเหตุถึงตัวเอง - อ่าน API! : 0)
Yuri Feldman

ลักษณะการทำงานเหมือนกันกับos.listdir: * nix OS ส่งคืนไฟล์ตามลำดับตัวอักษรและ (ทำให้ฉันต้องแปลกใจ!) สิ่งนี้ชัดเจนในเอกสาร : "รายการอยู่ในลำดับที่กำหนดเอง"
Joël

คำตอบ:


112

ls -Uมันอาจจะไม่เรียงที่ทั้งหมดและใช้คำสั่งที่ปรากฏในรายการระบบแฟ้มคือหนึ่งที่คุณได้รับเมื่อใช้ (อย่างน้อยในเครื่องของฉันสิ่งนี้จะสร้างคำสั่งเดียวกันกับรายการที่globตรงกัน)


1
ใช่เว้นแต่จะใช้ความพยายามพิเศษมันจะแสดงรายการตามที่ระบบปฏิบัติการจัดเตรียมไว้ให้ เช่นเดียวกับคำสั่ง "ค้นหา" ใน Unix มันเพียงทิ้งรายการตามลำดับที่มาจากโครงสร้างข้อมูลที่ใช้โดยระบบไฟล์พื้นฐาน คุณไม่ควรตั้งสมมุติฐานใด ๆ เกี่ยวกับการเรียงลำดับแม้ว่าคุณจะเห็นว่าไฟล์ดูเหมือนจะปรากฏในลำดับการสร้าง
Raúl Salinas-Monteagudo

424

คำสั่งซื้อนั้นเป็นไปตามอำเภอใจ แต่คุณสามารถจัดเรียงได้เอง

หากคุณต้องการเรียงตามชื่อ:

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

เรียงตามเวลาแก้ไข:

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

จัดเรียงตามขนาด:

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

เป็นต้น


1
files = glob.glob('teksty/*')ฉันมีไฟล์ที่ชื่อเป็นเพียงจำนวนเต็มโดยไม่มีนามสกุลดังนั้นฉันใช้: คำสั่งซื้อจะได้รับจากน้ำหรือไม่
andilabs

3
@ malgs ไม่นั่นไม่ใช่คำถามที่ฉันตั้งใจจะถาม สิ่งที่ฉันอยากรู้ก็คือคำตอบโดย Xion
Martin Thoma

และสิ่งที่เกี่ยวกับการจัดเรียงตามวันที่สร้าง แต่ตามเวลาที่สร้าง เพราะมันแสดงไฟล์ใหม่ล่าสุดให้ฉันก่อน ฉันจะรับรายการจากไฟล์เก่าไปจนถึงใหม่ล่าสุดได้อย่างไร ขอบคุณ!
joaquindev

1
โปรดทราบว่า getmtime และ getSize จะค่อนข้างแพง - ทำเช่นนี้สำหรับไฟล์จำนวนมากอาจใช้เวลาสักครู่ ..
drevicko

53

โดยการตรวจสอบซอร์สโค้ดของglob.globคุณเห็นว่ามันโทรภายในos.listdirอธิบายไว้ที่นี่:

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

ประโยคสำคัญ: os.listdir (เส้นทาง) ส่งคืนรายการที่มีชื่อของรายการในไดเรกทอรีที่กำหนดโดยเส้นทาง รายการอยู่ในลำดับที่กำหนดเอง ไม่รวมรายการพิเศษ '.' และ '.. ' แม้ว่าจะมีอยู่ในไดเรกทอรี

การสั่งซื้อโดยพลการ :)


14

glob.glob () เป็นตัวล้อมรอบ os.listdir () ดังนั้นระบบปฏิบัติการที่อยู่ภายใต้การดูแลจะรับผิดชอบการส่งข้อมูล โดยทั่วไป: คุณไม่สามารถตั้งสมมติฐานในการสั่งซื้อได้ที่นี่ สมมติฐานพื้นฐานคือไม่มีการสั่งซื้อ หากคุณต้องการเรียงลำดับ: เรียงลำดับในระดับแอปพลิเคชัน


13

คำสั่งซื้อโดยพลการ แต่มีหลายวิธีในการจัดเรียง หนึ่งในนั้นคือ

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

คำตอบของคุณสนับสนุนอะไรเมื่อเปรียบเทียบกับคำตอบที่มีอยู่
Martin Thoma

2
@MartinThoma ฉันมีปัญหากับการเรียงลำดับไม่เรียงชื่อไฟล์ถ้าจำนวนเต็มในไฟล์ไม่เป็นศูนย์ การเรียงลำดับเริ่มต้นที่ 1,000 ขึ้นไปจนถึงจำนวนเต็มสูงสุดใด ๆ แล้วเริ่มต้นใหม่จากจำนวนเต็มที่น้อยที่สุด ถ้าฉันเรียงตัวเลขให้เป็นศูนย์เพียงแค่เรียกเรียงบนไฟล์จะเรียงลำดับพวกเขาอย่างสมบูรณ์ ดังนั้นฉันคิดว่าวิธีนี้แก้ปัญหาเมื่อเรียงลำดับเพียงอย่างเดียวไม่ทำงาน
Will.Evo

1
@ Will.Evo ลองใช้natsort: from natsort import natsorted; files = natsorted(files).
Martin Thoma

คำตอบของคุณช่วย!
Vineet

12

ฉันมีปัญหาที่คล้ายกันglobคือส่งคืนรายชื่อไฟล์ตามลำดับโดยพลการ แต่ฉันต้องการที่จะผ่านพวกเขาตามลำดับตัวเลขตามที่ระบุโดยชื่อไฟล์ นี่คือวิธีที่ฉันได้รับ:

ไฟล์ของฉันถูกส่งคืนโดยglobบางสิ่งเช่น:

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

ฉันจัดเรียงรายการในสถานที่เพื่อทำสิ่งนี้ฉันได้สร้างฟังก์ชั่น:

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

ฟังก์ชั่นนี้จะส่งคืนส่วนที่เป็นตัวเลขของชื่อไฟล์และแปลงเป็นจำนวนเต็มจากนั้นฉันเรียกว่าวิธีการเรียงลำดับในรายการเช่น:

myList.sort(key=sortKeyFunc)

สิ่งนี้ส่งคืนรายการดังกล่าว:

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

ฉันคิดว่ามันดีกว่าที่จะใช้os.path.splitext(os.path.basename(s))[0]แทนos.path.basename(s)[:-4]ดังนั้นนิยามของฟังก์ชันจะเป็น def sortKeyFunc(s): return int(os.path.splitext(os.path.basename(s))[0])
ePandit

1

หากคุณสงสัยเกี่ยวกับสิ่งที่ glob.glob ได้ทำในระบบของคุณในอดีตและไม่สามารถเพิ่มการsortedโทรได้การสั่งซื้อจะสอดคล้องกับระบบไฟล์ Mac HFS +และจะเรียงตามลำดับการข้ามผ่านระบบ Unix อื่น ๆ ดังนั้นมันน่าจะถูกกำหนดไว้แล้วเว้นแต่ว่าระบบไฟล์พื้นฐานถูกจัดระเบียบใหม่ซึ่งสามารถเกิดขึ้นได้หากไฟล์ถูกเพิ่มลบเปลี่ยนชื่อลบย้ายย้าย ฯลฯ


APFS บน macOS เกี่ยวกับอะไร?
บอริส

1

จากวิธีการแก้ปัญหาของ @Johan La Rooy การเรียงลำดับรูปภาพที่ใช้sorted(glob.glob('*.png'))ไม่ได้ผลสำหรับฉันรายการส่งออกยังไม่ได้เรียงตามชื่อ

อย่างไรก็ตามการsorted(glob.glob('*.png'), key=os.path.getmtime)ทำงานอย่างสมบูรณ์แบบ

ฉันสับสนเล็กน้อยว่าการเรียงลำดับโดยชื่อของพวกเขาไม่ทำงานที่นี่

ขอบคุณ @Martin Thoma สำหรับการโพสต์คำถามที่ยอดเยี่ยมนี้และ @Johan La Rooy สำหรับวิธีแก้ปัญหาที่เป็นประโยชน์


-1

กรุณาลองรหัสนี้:

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

นั่นเป็นวิธีที่ฉันทำกรณีเฉพาะของฉัน หวังว่ามันจะเป็นประโยชน์


1
คุณควรเปลี่ยนคำตอบเพื่อให้เหมาะกับคำถาม
CodenameLambda

1
คำถามไม่ได้เกี่ยวกับการเรียงลำดับ ฉันรู้วิธีการจัดเรียง คำถามเกี่ยวกับการสั่งซื้อเริ่มต้น
Martin Thoma

1
ขอบคุณสำหรับข้อมูลโค้ดนี้ซึ่งอาจให้ความช่วยเหลือได้ทันที คำอธิบายที่เหมาะสมจะช่วยเพิ่มมูลค่าทางการศึกษาอย่างมากโดยแสดงให้เห็นว่าทำไมนี่จึงเป็นทางออกที่ดีสำหรับปัญหาและจะทำให้มีประโยชน์มากขึ้นสำหรับผู้อ่านในอนาคตที่มีคำถามคล้ายกัน แต่ไม่เหมือนกัน โปรดแก้ไขคำตอบของคุณเพื่อเพิ่มคำอธิบายและระบุข้อ จำกัด และสมมติฐานที่ใช้
Toby Speight
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.