Bagaimana cara membatasi os.walk
untuk hanya mengembalikan file di direktori yang saya sediakan?
def _dir_list(self, dir_name, whitelist):
outputList = []
for root, dirs, files in os.walk(dir_name):
for f in files:
if os.path.splitext(f)[1] in whitelist:
outputList.append(os.path.join(root, f))
else:
self._email_to_("ignore")
return outputList
files_with_full_path = [f.path for f in os.scandir(dir) if f.is_file()]
. Jika Anda hanya perlu menggunakan nama file,f.name
bukanf.path
. Ini adalah solusi tercepat dan jauh lebih cepat daripada yang mana punwalk
ataulistdir
, lihat stackoverflow.com/a/40347279/2441026 .Jawaban:
Gunakan
walklevel
fungsinya.Ini berfungsi seperti
os.walk
, tetapi Anda dapat meneruskannya kelevel
parameter yang menunjukkan seberapa dalam rekursi akan berjalan.sumber
dirs = []
dandirs = None
tetapi itu tidak berhasil.map(dirs.remove, dirs)
bekerja, tetapi dengan beberapa pesan '[Tidak Ada]' yang tidak diinginkan dicetak. Jadi, mengapadel dirs[:]
secara khusus?topdown=False
di os.walk. Lihat paragraf ke-4 dalam dokumen :Modifying dirnames when topdown is False has no effect on the behavior of the walk, because in bottom-up mode the directories in dirnames are generated before dirpath itself is generated.
dirs = []
dandirs = None
tidak akan berfungsi karena mereka hanya membuat objek baru yang tidak terkait dan menetapkan namanyadirs
. Objek daftar asli perlu dimodifikasi di tempat, bukan namanyadirs
.Jangan gunakan os.walk.
Contoh:
sumber
os.path.isfile
danos.path.isdir
memungkinkan Anda membedakan. Saya tidak mengerti, karenaos.path.isfile
ada dalam kode contoh sejak '08 dan komentar Anda berasal dari '16. Ini jelas merupakan jawaban yang lebih baik, karena Anda tidak bermaksud untuk menjalankan direktori, tetapi untuk mendaftarnya.walk
segera memberi Anda daftar terpisah dari dirs dan file..next()
) dan lebih dekat dengan ide Anda.os.scandir
fungsi yang memungkinkan interaksi file-atau-direktori-objek yang lebih canggih. Lihat jawaban saya di bawah iniMenurut saya solusinya sebenarnya sangat sederhana.
menggunakan
untuk hanya melakukan iterasi pertama pada loop for, harus ada cara yang lebih elegan.
Pertama kali Anda memanggil os.walk, ia mengembalikan tulip untuk direktori saat ini, kemudian pada perulangan berikutnya isi direktori berikutnya.
Ambil skrip asli dan tambahkan jeda .
sumber
Saran untuk digunakan
listdir
itu bagus. Jawaban langsung untuk pertanyaan Anda dengan Python 2 adalahroot, dirs, files = os.walk(dir_name).next()
.Sintaks setara Python 3 adalah
root, dirs, files = next(os.walk(dir_name))
sumber
root, dirs, files = os.walk(dir_name).next()
memberi sayaAttributeError: 'generator' object has no attribute 'next'
root, dirs, files = next(os.walk(dir_name))
dan kemudian variabelroot, dirs, files
hanya akan sesuai dengan variabel generator didir_name
level.Anda bisa menggunakan
os.listdir()
yang mengembalikan daftar nama (untuk file dan direktori) di direktori tertentu. Jika Anda perlu membedakan antara file dan direktori, panggilos.stat()
setiap nama.sumber
Jika Anda memiliki persyaratan yang lebih kompleks daripada hanya direktori teratas (misalnya mengabaikan direktori VCS, dll.), Anda juga dapat mengubah daftar direktori untuk mencegah os.walk berulang kali melewatinya.
yaitu:
Catatan - hati-hati untuk mengubah daftar, bukan hanya mengulangnya. Jelas os.walk tidak tahu tentang rebinding eksternal.
sumber
sumber
Ide yang sama dengan
listdir
, tetapi lebih pendek:sumber
Merasa ingin membuang 2 pence saya.
sumber
Dengan Python 3, saya bisa melakukan ini:
sumber
Sejak Python 3.5 Anda dapat menggunakan
os.scandir
sebagai penggantios.listdir
. Alih-alih string, Anda mendapatkan iteratorDirEntry
objek sebagai gantinya. Dari dokumen:Anda dapat mengakses nama objek
DirEntry.name
yang kemudian setara dengan output darios.listdir
sumber
scandir()
, karena jauh lebih cepat daripadalistdir()
. Lihat tolok ukur di sini: stackoverflow.com/a/40347279/2441026 .Anda juga bisa melakukan hal berikut:
sumber
Beginilah cara saya menyelesaikannya
sumber
Ada kendala saat menggunakan listdir. Os.path.isdir (pengenal) harus berupa jalur absolut. Untuk memilih subdirektori yang Anda lakukan:
Alternatifnya adalah mengubah ke direktori untuk melakukan pengujian tanpa os.path.join ().
sumber
Anda dapat menggunakan potongan ini
sumber
buat daftar pengecualian, gunakan fnmatch untuk melewati struktur direktori dan lakukan prosesnya
sama seperti untuk 'termasuk':
sumber
Mengapa tidak menggunakan a
range
danos.walk
dikombinasikan denganzip
? Bukan solusi terbaik, tapi akan berhasil juga.Contohnya seperti ini:
Bekerja untuk saya di python 3.
Juga: A
break
lebih sederhana juga btw. (Lihat jawaban dari @Pieter)sumber
Sedikit perubahan pada jawaban Alex, tetapi menggunakan
__next__()
:print(next(os.walk('d:/'))[2])
atauprint(os.walk('d:/').__next__()[2])
dengan
[2]
menjadifile
diroot, dirs, file
disebutkan dalam jawaban lainnyasumber
folder root berubah untuk setiap direktori yang ditemukan os.walk. Saya memecahkan memeriksa apakah root == direktori
sumber
sumber