Saya sering menggunakan python untuk memproses direktori data. Baru-baru ini, saya memperhatikan bahwa urutan default daftar telah berubah menjadi sesuatu yang hampir tidak masuk akal. Misalnya, jika saya berada di direktori saat ini yang berisi subdirektori berikut: run01, run02, ... run19, run20, lalu saya membuat daftar dari perintah berikut:
dir = os.listdir(os.getcwd())
maka saya biasanya mendapatkan daftar dalam urutan ini:
dir = ['run01', 'run18', 'run14', 'run13', 'run12', 'run11', 'run08', ... ]
dan seterusnya. Urutannya dulu alfanumerik. Tetapi tatanan baru ini tetap ada pada saya untuk sementara waktu sekarang.
Apa yang menentukan urutan (ditampilkan) dari daftar ini?
python
list
directory-listing
listdir
marshall.ward
sumber
sumber
listdir
keluaran yang diurutkan . Saya tidak yakin mengapa pertanyaan itu digabungkan.Jawaban:
Saya pikir urutannya ada hubungannya dengan cara file diindeks di FileSystem Anda. Jika Anda benar-benar ingin membuatnya mematuhi beberapa urutan, Anda selalu dapat mengurutkan daftar setelah mendapatkan file.
sumber
Anda dapat menggunakan
sorted
fungsi bawaan untuk mengurutkan string sesuai keinginan Anda. Berdasarkan apa yang Anda gambarkan,Atau, Anda dapat menggunakan
.sort
metode daftar:Saya pikir harus melakukan trik.
Perhatikan bahwa urutan
os.listdir
mendapatkan nama file mungkin sepenuhnya bergantung pada sistem file Anda.sumber
sorted(listdir)
bekerja untuk saya.listdir.sort()
memberi saya: TypeError: Objek 'NoneType' tidak dapatreverse=True
untuk membuatnya agak menurun.sorted
hal yang ditulis pertama kali melakukannya dalam satu baris OK?Sesuai dokumentasi :
Urutan tidak dapat diandalkan dan merupakan artefak dari sistem file.
Untuk mengurutkan hasil, gunakan
sorted(os.listdir(path))
.sumber
Python untuk alasan apa pun tidak dilengkapi dengan cara bawaan untuk memiliki pengurutan alami (artinya 1, 2, 10, bukan 1, 10, 2), jadi Anda harus menulisnya sendiri:
Sekarang Anda dapat menggunakan fungsi ini untuk mengurutkan daftar:
MASALAH: Jika Anda menggunakan fungsi di atas untuk mengurutkan string (misalnya nama folder) dan ingin mereka diurutkan seperti yang dilakukan Windows Explorer, ini tidak akan berfungsi dengan baik dalam beberapa kasus edge.
Fungsi pengurutan ini akan mengembalikan hasil yang salah pada Windows, jika Anda memiliki nama folder dengan karakter 'khusus' tertentu di dalamnya. Misalnya fungsi ini akan mengurutkan
1, !1, !a, a
, sedangkan Windows Explorer akan mengurutkan!1, 1, !a, a
.Jadi jika Anda ingin mengurutkan persis seperti yang dilakukan Windows Explorer dengan Python, Anda harus menggunakan fungsi bawaan Windows bawaan StrCmpLogicalW melalui ctypes (ini tentu saja tidak akan berfungsi pada Unix):
Fungsi ini sedikit lebih lambat dari
sorted_alphanumeric()
.Bonus:
winsort
juga dapat mengurutkan jalur lengkap di Windows .Alternatifnya, terutama jika Anda menggunakan Unix, Anda dapat menggunakan
natsort
library (pip install natsort
) untuk mengurutkan menurut jalur lengkap dengan cara yang benar (artinya subfolder di posisi yang benar).Anda dapat menggunakannya seperti ini untuk mengurutkan jalur lengkap:
Jangan menggunakannya untuk pengurutan normal hanya nama folder (atau string secara umum), karena ini sedikit lebih lambat dari
sorted_alphanumeric()
fungsi di atas.natsorted
perpustakaan akan memberi Anda hasil yang salah jika Anda mengharapkan pengurutan Windows Explorer, jadi gunakanwinsort()
untuk itu.sumber
print( sorted_aphanumeric(["1", "10", "2", "foo_10", "foo_8"]) )
->['1', '2', '10', 'foo_8', 'foo_10']
. Persis seperti yang diharapkan.natsorted
untuk menerapkan fungsionalitas pencocokan Windows Explorer. Mungkin Anda harus memberikan solusi? github.com/SethMMorton/natsort/issues/41Saya pikir secara default urutan ditentukan dengan nilai ASCII. Solusi untuk masalah ini adalah ini
sumber
Mungkin hanya urutan C yang
readdir()
kembali. Coba jalankan program C ini:Garis build harus seperti ini
gcc -o foo foo.c
.PS Hanya menjalankan ini dan kode Python Anda, dan mereka berdua memberi saya keluaran yang diurutkan, jadi saya tidak dapat mereproduksi apa yang Anda lihat.
sumber
Sebagai Dalam kasus kebutuhan saya, saya memiliki kasus seperti di
row_163.pkl
sinios.path.splitext('row_163.pkl')
akan membobolnya('row_163', '.pkl')
jadi perlu membaginya berdasarkan '_' juga.tetapi dalam kasus kebutuhan Anda, Anda dapat melakukan sesuatu seperti
dimana
dan juga untuk pengambilan direktori dapat Anda lakukan
sorted(os.listdir(path))
dan untuk kasus sejenis
'run01.txt'
atau'run01.csv'
bisa kamu lakukan seperti inisumber
Saya menemukan "sort" tidak selalu melakukan apa yang saya harapkan. misalnya, saya memiliki direktori seperti di bawah ini, dan "sort" memberi saya hasil yang sangat aneh:
Sepertinya itu membandingkan karakter pertama terlebih dahulu, jika itu yang terbesar, itu akan menjadi yang terakhir.
sumber
('5' > '403') is True
.Dari dokumentasi :
Ini berarti bahwa urutannya mungkin bergantung pada OS / filesystem, tidak memiliki urutan yang berarti, dan oleh karena itu tidak dijamin menjadi sesuatu secara khusus. Seperti banyak jawaban yang disebutkan: jika disukai, daftar yang diambil dapat diurutkan.
Bersulang :)
sumber
Jawaban Elliot menyelesaikannya dengan sempurna tetapi karena ini adalah sebuah komentar, ia luput dari perhatian sehingga dengan tujuan membantu seseorang, saya mengulanginya sebagai solusi.
Gunakan perpustakaan natsort:
Instal pustaka dengan perintah berikut untuk Ubuntu dan versi Debian lainnya
Python 2
Python 3
Detail tentang cara menggunakan perpustakaan ini ditemukan di sini
sumber
sorted()
! Terima kasihKombinasi yang diusulkan
os.listdir
dansorted
perintah menghasilkan hasil yang sama sepertils -l
perintah di Linux. Contoh berikut memverifikasi asumsi ini:Jadi, untuk seseorang yang ingin mereproduksi hasil dari
ls -l
perintah terkenal di kode python mereka,sorted( os.listdir( DIR ) )
bekerja dengan cukup baik.sumber
sumber