मैं निर्देशिका की सभी फ़ाइलों को कैसे सूचीबद्ध करूं?


3473

मैं पायथन में एक निर्देशिका की सभी फाइलों को कैसे सूचीबद्ध कर सकता हूं और उन्हें एक में जोड़ सकता हूं list?


जवाबों:


4207

os.listdir()आपको एक निर्देशिका - फ़ाइलों और निर्देशिकाओं में वह सब कुछ मिलेगा ।

यदि आप केवल फाइलें चाहते हैं , तो आप इसका उपयोग करके या तो फ़िल्टर कर सकते हैं os.path:

from os import listdir
from os.path import isfile, join
onlyfiles = [f for f in listdir(mypath) if isfile(join(mypath, f))]

या आप उपयोग कर सकते हैं os.walk()जो आपके द्वारा देखी गई प्रत्येक निर्देशिका के लिए दो सूचियों को प्राप्त करेगा - आपके लिए फ़ाइलों और डायरियों में विभाजित करना । यदि आप केवल शीर्ष निर्देशिका चाहते हैं तो आप पहली बार यह पैदावार तोड़ सकते हैं

from os import walk

f = []
for (dirpath, dirnames, filenames) in walk(mypath):
    f.extend(filenames)
    break

87
थोड़ा सरल: (_, _, filenames) = walk(mypath).next() (यदि आप आश्वस्त हैं कि वॉक कम से कम एक मान लौटाएगा, जो इसे होना चाहिए।)
मिस्टरबी

9
पूर्ण रास्तों को संग्रहीत करने के लिए थोड़ा संशोधन: (dirpath, dirnames, filenames) os.walk (mypath) में: checkum_files.extend (os.path.join (dirathath, filename) फ़ाइल नाम में फ़ाइल नाम के लिए) तोड़
okigan

150
f.extend(filenames)के बराबर नहीं है f = f + filenames। इन-प्लेस extendको संशोधित करेगा f, जबकि जोड़ना एक नई मेमोरी लोकेशन में एक नई सूची बनाता है। इसका मतलब extendआम तौर पर की तुलना में अधिक कुशल है +, लेकिन कभी-कभी यह भ्रम पैदा कर सकता है कि क्या कई ऑब्जेक्ट सूची में संदर्भ रखते हैं। अंत में, यह ध्यान देने योग्य है कि f += filenamesइसके बराबर है f.extend(filenames), नहीं f = f + filenames
बेंजामिन हॉजसन

30
_, _, filenames = next(walk(mypath), (None, None, []))
@ मिस्टरबी

35
अजगर में 3.x का उपयोग करें(_, _, filenames) = next(os.walk(mypath))
ET-CS

1676

मैं globमॉड्यूल का उपयोग करना पसंद करता हूं , क्योंकि यह पैटर्न मिलान और विस्तार करता है।

import glob
print(glob.glob("/home/adam/*.txt"))

यह क्वियर की गई फ़ाइलों के साथ एक सूची लौटाएगा:

['/home/adam/file1.txt', '/home/adam/file2.txt', .... ]


31
स्पष्ट करने के लिए, यह "पूर्ण पथ" वापस नहीं करता है ; यह केवल ग्लोब के विस्तार को वापस करता है, जो भी हो। उदाहरण के लिए, यह देखते हुए /home/user/foo/bar/hello.txt, तो, निर्देशिका में चल रहा है, तो foo, glob("bar/*.txt")वापस आ जाएगी bar/hello.txt। ऐसे मामले हैं जब आप वास्तव में पूर्ण (यानी, पूर्ण) पथ चाहते हैं; उन मामलों के लिए, stackoverflow.com/questions/51520/…
माइकल

1
संबंधित: ग्लोब के साथ पुनरावर्ती फ़ाइलें ढूंढें: stackoverflow.com/a/2186565/4561887
गेब्रियल स्टेपल्स

6
इस सवाल का जवाब नहीं है। glob.glob("*")चाहेंगे।
जीन फ़्राँस्वा Fabre

सुंदर!!!! इसलिए .... x=glob.glob("../train/*.png")जब तक मैं फ़ोल्डर का नाम जानता हूं, तब तक मुझे अपने रास्तों की एक सरणी दे देंगे। इतना ठंडा!
जेनिफर क्रॉस्बी

856

पायथन 2 और 3 के साथ फ़ाइलों की एक सूची प्राप्त करें


os.listdir()

वर्तमान निर्देशिका में सभी फाइलें (और निर्देशिका) कैसे प्राप्त करें (पायथन 3)

इसके बाद, पायथन 3 में वर्तमान निर्देशिका में केवल फाइलों को पुनः प्राप्त करने os और उपयोग करने के लिए सरल तरीके हैं listdir()। आगे की खोज में, निर्देशिका में फ़ोल्डरों को वापस करने का तरीका दिखाया जाएगा, लेकिन आपके पास उपनिर्देशिका में फ़ाइल नहीं होगी, इसके लिए आप चल सकते हैं - बाद में चर्चा की)।

 import os
 arr = os.listdir()
 print(arr)

 >>> ['$RECYCLE.BIN', 'work.txt', '3ebooks.txt', 'documents']

glob

मुझे उसी प्रकार की फ़ाइल या सामान्य रूप से किसी चीज़ का चयन करना आसान लगता है। निम्नलिखित उदाहरण देखें:

import glob

txtfiles = []
for file in glob.glob("*.txt"):
    txtfiles.append(file)

glob सूची समझ के साथ

import glob

mylist = [f for f in glob.glob("*.txt")]

glob एक समारोह के साथ

फ़ंक्शन दिए गए एक्सटेंशन (.txt, .docx ecc।) की एक सूची तर्क में देता है

import glob

def filebrowser(ext=""):
    "Returns files with an extension"
    return [f for f in glob.glob(f"*{ext}")]

x = filebrowser(".txt")
print(x)

>>> ['example.txt', 'fb.txt', 'intro.txt', 'help.txt']

glob पिछले कोड का विस्तार

फ़ंक्शन अब फ़ाइल की एक सूची लौटाता है जो स्ट्रिंग के साथ मेल खाता है जिसे आप तर्क के रूप में पास करते हैं

import glob

def filesearch(word=""):
    """Returns a list with all files with the word/extension in it"""
    file = []
    for f in glob.glob("*"):
        if word[0] == ".":
            if f.endswith(word):
                file.append(f)
                return file
        elif word in f:
            file.append(f)
            return file
    return file

lookfor = "example", ".py"
for w in lookfor:
    print(f"{w:10} found => {filesearch(w)}")

उत्पादन

example    found => []
.py        found => ['search.py']

के साथ पूर्ण पथ नाम प्राप्त करना os.path.abspath

जैसा कि आपने देखा, आपके पास उपरोक्त कोड में फ़ाइल का पूर्ण पथ नहीं है। यदि आपको निरपेक्ष पथ की आवश्यकता है, तो आप os.pathमॉड्यूल के किसी अन्य फ़ंक्शन का उपयोग कर सकते हैं _getfullpathname, जिस फ़ाइल को आप os.listdir()एक तर्क के रूप में प्राप्त करते हैं। पूरे रास्ते पर चलने के अन्य तरीके हैं, जैसा कि हम बाद में जांच करेंगे (मैंने प्रतिस्थापित किया, जैसा कि मेक्समेक्स द्वारा सुझाया गया है, _getfullpathname with abspath)।

 import os
 files_path = [os.path.abspath(x) for x in os.listdir()]
 print(files_path)

 >>> ['F:\\documenti\applications.txt', 'F:\\documenti\collections.txt']

सभी उपनिर्देशिकाओं में एक प्रकार की फ़ाइल का पूर्ण पथ नाम प्राप्त करें walk

मुझे कई निर्देशिकाओं में सामान खोजने के लिए यह बहुत उपयोगी लगता है, और इससे मुझे एक फ़ाइल खोजने में मदद मिली जिसके बारे में मुझे नाम याद नहीं था:

import os

# Getting the current work directory (cwd)
thisdir = os.getcwd()

# r=root, d=directories, f = files
for r, d, f in os.walk(thisdir):
    for file in f:
        if file.endswith(".docx"):
            print(os.path.join(r, file))

os.listdir(): वर्तमान निर्देशिका में फ़ाइलें प्राप्त करें (पायथन 2)

पायथन 2 में, यदि आप वर्तमान निर्देशिका में फ़ाइलों की सूची चाहते हैं, तो आपको तर्क '' के रूप में देना होगा। या os.getcwd () में os.listdir विधि।

 import os
 arr = os.listdir('.')
 print(arr)

 >>> ['$RECYCLE.BIN', 'work.txt', '3ebooks.txt', 'documents']

डायरेक्टरी ट्री में ऊपर जाने के लिए

# Method 1
x = os.listdir('..')

# Method 2
x= os.listdir('/')

फ़ाइलें प्राप्त करें: os.listdir()एक विशेष निर्देशिका में (पायथन 2 और 3)

 import os
 arr = os.listdir('F:\\python')
 print(arr)

 >>> ['$RECYCLE.BIN', 'work.txt', '3ebooks.txt', 'documents']

के साथ एक विशेष उपनिर्देशिका की फ़ाइलें प्राप्त करें os.listdir()

import os

x = os.listdir("./content")

os.walk('.') - वर्तमान निर्देशिका

 import os
 arr = next(os.walk('.'))[2]
 print(arr)

 >>> ['5bs_Turismo1.pdf', '5bs_Turismo1.pptx', 'esperienza.txt']

next(os.walk('.')) तथा os.path.join('dir', 'file')

 import os
 arr = []
 for d,r,f in next(os.walk("F:\\_python")):
     for file in f:
         arr.append(os.path.join(r,file))

 for f in arr:
     print(files)

>>> F:\\_python\\dict_class.py
>>> F:\\_python\\programmi.txt

next(os.walk('F:\\') - पूर्ण पथ प्राप्त करें - सूची की समझ

 [os.path.join(r,file) for r,d,f in next(os.walk("F:\\_python")) for file in f]

 >>> ['F:\\_python\\dict_class.py', 'F:\\_python\\programmi.txt']

os.walk - पूर्ण पथ प्राप्त करें - सब डिर में सभी फाइलें **

x = [os.path.join(r,file) for r,d,f in os.walk("F:\\_python") for file in f]
print(x)

>>> ['F:\\_python\\dict.py', 'F:\\_python\\progr.txt', 'F:\\_python\\readl.py']

os.listdir() - केवल txt फ़ाइलें प्राप्त करें

 arr_txt = [x for x in os.listdir() if x.endswith(".txt")]
 print(arr_txt)

 >>> ['work.txt', '3ebooks.txt']

globफ़ाइलों का पूर्ण पथ प्राप्त करने के लिए उपयोग करना

अगर मुझे फ़ाइलों के पूर्ण पथ की आवश्यकता होनी चाहिए:

from path import path
from glob import glob
x = [path(f).abspath() for f in glob("F:\\*.txt")]
for f in x:
    print(f)

>>> F:\acquistionline.txt
>>> F:\acquisti_2018.txt
>>> F:\bootstrap_jquery_ecc.txt

os.path.isfileसूची में निर्देशिकाओं से बचने के लिए उपयोग करना

import os.path
listOfFiles = [f for f in os.listdir() if os.path.isfile(f)]
print(listOfFiles)

>>> ['a simple game.py', 'data.txt', 'decorator.py']

pathlibपायथन 3.4 से उपयोग करना

import pathlib

flist = []
for p in pathlib.Path('.').iterdir():
    if p.is_file():
        print(p)
        flist.append(p)

 >>> error.PNG
 >>> exemaker.bat
 >>> guiprova.mp3
 >>> setup.py
 >>> speak_gui2.py
 >>> thumb.PNG

के साथ list comprehension:

flist = [p for p in pathlib.Path('.').iterdir() if p.is_file()]

वैकल्पिक रूप से, के pathlib.Path()बजाय का उपयोग करेंpathlib.Path(".")

Pathlib में ग्लोब विधि का प्रयोग करें। पैथ ()

import pathlib

py = pathlib.Path().glob("*.py")
for file in py:
    print(file)

>>> stack_overflow_list.py
>>> stack_overflow_list_tkinter.py

Os.walk के साथ सभी और केवल फाइलें प्राप्त करें

import os
x = [i[2] for i in os.walk('.')]
y=[]
for t in x:
    for f in t:
        y.append(f)
print(y)

>>> ['append_to_list.py', 'data.txt', 'data1.txt', 'data2.txt', 'data_180617', 'os_walk.py', 'READ2.py', 'read_data.py', 'somma_defaltdic.py', 'substitute_words.py', 'sum_data.py', 'data.txt', 'data1.txt', 'data_180617']

अगली के साथ केवल फाइलें प्राप्त करें और एक निर्देशिका में चलें

 import os
 x = next(os.walk('F://python'))[2]
 print(x)

 >>> ['calculator.bat','calculator.py']

अगली के साथ केवल निर्देशिका प्राप्त करें और एक निर्देशिका में चलें

 import os
 next(os.walk('F://python'))[1] # for the current dir use ('.')

 >>> ['python3','others']

सभी उप-नाम नामों के साथ प्राप्त करें walk

for r,d,f in os.walk("F:\\_python"):
    for dirs in d:
        print(dirs)

>>> .vscode
>>> pyexcel
>>> pyschool.py
>>> subtitles
>>> _metaprogramming
>>> .ipynb_checkpoints

os.scandir() पायथन 3.5 और अधिक से अधिक

import os
x = [f.name for f in os.scandir() if f.is_file()]
print(x)

>>> ['calculator.bat','calculator.py']

# Another example with scandir (a little variation from docs.python.org)
# This one is more efficient than os.listdir.
# In this case, it shows the files only in the current directory
# where the script is executed.

import os
with os.scandir() as i:
    for entry in i:
        if entry.is_file():
            print(entry.name)

>>> ebookmaker.py
>>> error.PNG
>>> exemaker.bat
>>> guiprova.mp3
>>> setup.py
>>> speakgui4.py
>>> speak_gui2.py
>>> speak_gui3.py
>>> thumb.PNG

उदाहरण:

पूर्व। 1: उपनिर्देशिकाओं में कितनी फाइलें हैं?

इस उदाहरण में, हम उन फ़ाइलों की संख्या की तलाश करते हैं जो सभी निर्देशिका और इसके उपनिर्देशिकाओं में शामिल हैं।

import os

def count(dir, counter=0):
    "returns number of files in dir and subdirs"
    for pack in os.walk(dir):
        for f in pack[2]:
            counter += 1
    return dir + " : " + str(counter) + "files"

print(count("F:\\python"))

>>> 'F:\\\python' : 12057 files'

Ex.2: एक डायरेक्टरी से दूसरी में सभी फाइलों को कॉपी कैसे करें?

आपके कंप्यूटर में एक प्रकार की सभी फ़ाइलों (डिफ़ॉल्ट: pptx) को खोजने और उन्हें एक नए फ़ोल्डर में कॉपी करने के लिए एक स्क्रिप्ट।

import os
import shutil
from path import path

destination = "F:\\file_copied"
# os.makedirs(destination)

def copyfile(dir, filetype='pptx', counter=0):
    "Searches for pptx (or other - pptx is the default) files and copies them"
    for pack in os.walk(dir):
        for f in pack[2]:
            if f.endswith(filetype):
                fullpath = pack[0] + "\\" + f
                print(fullpath)
                shutil.copy(fullpath, destination)
                counter += 1
    if counter > 0:
        print('-' * 30)
        print("\t==> Found in: `" + dir + "` : " + str(counter) + " files\n")

for dir in os.listdir():
    "searches for folders that starts with `_`"
    if dir[0] == '_':
        # copyfile(dir, filetype='pdf')
        copyfile(dir, filetype='txt')


>>> _compiti18\Compito Contabilità 1\conti.txt
>>> _compiti18\Compito Contabilità 1\modula4.txt
>>> _compiti18\Compito Contabilità 1\moduloa4.txt
>>> ------------------------
>>> ==> Found in: `_compiti18` : 3 files

पूर्व। 3: कैसे एक txt फ़ाइल में सभी फ़ाइलों को प्राप्त करने के लिए

यदि आप सभी फ़ाइल नामों के साथ एक txt फ़ाइल बनाना चाहते हैं:

import os
mylist = ""
with open("filelist.txt", "w", encoding="utf-8") as file:
    for eachfile in os.listdir():
        mylist += eachfile + "\n"
    file.write(mylist)

उदाहरण: हार्ड ड्राइव की सभी फाइलों के साथ txt

"""
We are going to save a txt file with all the files in your directory.
We will use the function walk()
"""

import os

# see all the methods of os
# print(*dir(os), sep=", ")
listafile = []
percorso = []
with open("lista_file.txt", "w", encoding='utf-8') as testo:
    for root, dirs, files in os.walk("D:\\"):
        for file in files:
            listafile.append(file)
            percorso.append(root + "\\" + file)
            testo.write(file + "\n")
listafile.sort()
print("N. of files", len(listafile))
with open("lista_file_ordinata.txt", "w", encoding="utf-8") as testo_ordinato:
    for file in listafile:
        testo_ordinato.write(file + "\n")

with open("percorso.txt", "w", encoding="utf-8") as file_percorso:
    for file in percorso:
        file_percorso.write(file + "\n")

os.system("lista_file.txt")
os.system("lista_file_ordinata.txt")
os.system("percorso.txt")

एक पाठ फ़ाइल में C: \ की सभी फ़ाइल

यह पिछले कोड का एक छोटा संस्करण है। यदि आपको किसी अन्य स्थिति से प्रारंभ करने की आवश्यकता है, तो फ़ोल्डर को बदलना शुरू करें जहां फ़ाइलों को ढूंढना है। यह कोड मेरे कंप्यूटर पर पाठ फ़ाइल पर 50 mb उत्पन्न करता है और कुछ पूर्ण पथ के साथ फ़ाइलों के साथ 500.000 लाइनें कम है।

import os

with open("file.txt", "w", encoding="utf-8") as filewrite:
    for r, d, f in os.walk("C:\\"):
        for file in f:
            filewrite.write(f"{r + file}\n")

एक प्रकार के फ़ोल्डर में सभी पथों के साथ एक फ़ाइल कैसे लिखें

इस फ़ंक्शन के साथ आप एक txt फ़ाइल बना सकते हैं जिसमें उस प्रकार की फ़ाइल का नाम होगा जिसे आप खोजते हैं (उदा। Pngfile.txt) उस प्रकार की सभी फ़ाइलों का पूरा पथ। यह कभी-कभी उपयोगी हो सकता है, मुझे लगता है।

import os

def searchfiles(extension='.ttf', folder='H:\\'):
    "Create a txt file with all the file of a type"
    with open(extension[1:] + "file.txt", "w", encoding="utf-8") as filewrite:
        for r, d, f in os.walk(folder):
            for file in f:
                if file.endswith(extension):
                    filewrite.write(f"{r + file}\n")

# looking for png file (fonts) in the hard disk H:\
searchfiles('.png', 'H:\\')

>>> H:\4bs_18\Dolphins5.png
>>> H:\4bs_18\Dolphins6.png
>>> H:\4bs_18\Dolphins7.png
>>> H:\5_18\marketing html\assets\imageslogo2.png
>>> H:\7z001.png
>>> H:\7z002.png

(नई) सभी फाइलों को ढूंढें और उन्हें tkinter GUI के साथ खोलें

मैं सिर्फ इस 2019 में एक छोटे से डायर में सभी फाइलों को खोजने के लिए एक छोटा सा ऐप जोड़ना चाहता था और सूची में फ़ाइल के नाम पर डबल क्लिक करके उन्हें खोलने में सक्षम था। यहां छवि विवरण दर्ज करें

import tkinter as tk
import os

def searchfiles(extension='.txt', folder='H:\\'):
    "insert all files in the listbox"
    for r, d, f in os.walk(folder):
        for file in f:
            if file.endswith(extension):
                lb.insert(0, r + "\\" + file)

def open_file():
    os.startfile(lb.get(lb.curselection()[0]))

root = tk.Tk()
root.geometry("400x400")
bt = tk.Button(root, text="Search", command=lambda:searchfiles('.png', 'H:\\'))
bt.pack()
lb = tk.Listbox(root)
lb.pack(fill="both", expand=1)
lb.bind("<Double-Button>", lambda x: open_file())
root.mainloop()

13
यहां पूछे गए सवालों के बहुत से जवाबों का यह एक मिशाल है। यह समझाने के लायक भी हो सकता है कि कैवेट या अनुशंसित दृष्टिकोण क्या हैं। जब तक मैं यह भी नहीं जानता कि मैं एक ही काम करने के 20 तरीकों में से कोई एक तरीका नहीं जानता, जब तक कि मैं यह भी नहीं जानता कि कब उपयोग करना ज्यादा उचित है।
cs95

ठीक है, ASAP मैं अपने उत्तर पर एक नज़र डालूंगा और इसे और अधिक स्वच्छ बनाने की कोशिश करूँगा और तरीकों आदि के बीच अंतर के बारे में अधिक उपयोगी जानकारी के साथ
Giovanni G. PY

यदि फ़ाइलनाम में एक विकल्प है, तो आपको जाँच करके फ़ाइल के विस्तार का निर्धारण नहीं करना चाहिए। जो कई परेशानियों का कारण बन सकता है। मैं हमेशा जांच करने की सलाह देता हूं कि क्या फ़ाइलनाम विशेष प्रतिस्थापन के साथ समाप्त होता है।
ni1ight

ठीक है, @ n1light मैंने कोड बदल दिया ...
Giovanni G. PY

811
import os
os.listdir("somedirectory")

"somedirectory" में सभी फाइलों और निर्देशिकाओं की सूची लौटाएगा।


11
यह फाइलों के सापेक्ष पथ को लौटाता है, क्योंकि पूर्ण पथ के साथ तुलना मेंglob.glob
xji

22
@ जिआंगयांग: os.listdir()हमेशा केवल फ़ाइल नाम देता है (सापेक्ष पथ नहीं)। glob.glob()इनपुट पैटर्न के पथ प्रारूप से क्या रिटर्न मिलता है।
mklement0

os.listdir () -> यह हमेशा दिए गए स्थान के अंदर dir और फ़ाइल को सूचीबद्ध करता है। क्या केवल फाइलों को डायरेक्ट्री लिस्ट करने का कोई तरीका नहीं है?
रौना

160

फ़ाइलों की केवल सूची (कोई उपनिर्देशिका) प्राप्त करने के लिए एक-लाइन समाधान :

filenames = next(os.walk(path))[2]

या पूर्ण मार्ग:

paths = [os.path.join(path, fn) for fn in next(os.walk(path))[2]]

7
यदि आप पहले से ही केवल एक लाइनर है import osglob()मुझसे कम संक्षिप्त लगता है।
आर्टऑफवर्फ

4
ग्लोब के साथ समस्या यह है कि 'some.something' नामक फोल्डर ग्लोब ('/ home / adam /*.*') द्वारा लौटाया जाएगा
रेमी

6
OS X पर, एक बंडल नामक कुछ है। यह एक निर्देशिका है जिसे आम तौर पर फ़ाइल (जैसे .tar) के रूप में माना जाना चाहिए। क्या आप फ़ाइल या निर्देशिका के रूप में व्यवहार करना चाहते हैं? का उपयोग करके glob()इसे एक फ़ाइल के रूप में माना जाएगा। आपकी विधि इसे एक निर्देशिका के रूप में मानती है।
आर्टऑफवर्फ

132

एक निर्देशिका और उसके सभी उपनिर्देशिकाओं से पूर्ण फ़ाइल पथ प्राप्त करना

import os

def get_filepaths(directory):
    """
    This function will generate the file names in a directory 
    tree by walking the tree either top-down or bottom-up. For each 
    directory in the tree rooted at directory top (including top itself), 
    it yields a 3-tuple (dirpath, dirnames, filenames).
    """
    file_paths = []  # List which will store all of the full filepaths.

    # Walk the tree.
    for root, directories, files in os.walk(directory):
        for filename in files:
            # Join the two strings in order to form the full filepath.
            filepath = os.path.join(root, filename)
            file_paths.append(filepath)  # Add it to the list.

    return file_paths  # Self-explanatory.

# Run the above function and store its results in a variable.   
full_file_paths = get_filepaths("/Users/johnny/Desktop/TEST")

  • उपरोक्त फ़ंक्शन में मैंने जो पथ प्रदान किया था, उसमें 3 फाइलें थीं- उनमें से दो रूट डायरेक्टरी में थीं, और दूसरी सबफ़ोल्डर में "SUBFOLDER"। अब आप निम्न कार्य कर सकते हैं:
  • print full_file_paths जो सूची को प्रिंट करेगा:

    • ['/Users/johnny/Desktop/TEST/file1.txt', '/Users/johnny/Desktop/TEST/file2.txt', '/Users/johnny/Desktop/TEST/SUBFOLDER/file3.dat']

यदि आप चाहें, तो आप सामग्री को खोल सकते हैं और पढ़ सकते हैं, या केवल एक्सटेंशन वाली फाइलों पर ध्यान केंद्रित कर सकते हैं ".डाट" जैसे नीचे दिए गए कोड में:

for f in full_file_paths:
  if f.endswith(".dat"):
    print f

/Users/johnny/Desktop/TEST/SUBFOLDER/file3.dat


यह केवल और केवल एक ही उत्तर है।
थलचर

78

संस्करण ३.४ के बाद से इसके लिए निर्मित पुनरावृत्तियाँ हैं , जो इससे कहीं अधिक कुशल हैं os.listdir():

pathlib: संस्करण 3.4 में नया।

>>> import pathlib
>>> [p for p in pathlib.Path('.').iterdir() if p.is_file()]

PEP 428 के अनुसार , pathlibपुस्तकालय का उद्देश्य फाइल सिस्टम पथों को संभालने के लिए कक्षाओं का एक सरल पदानुक्रम प्रदान करना है और आम संचालन उपयोगकर्ता उन पर करते हैं।

os.scandir(): संस्करण 3.5 में नया।

>>> import os
>>> [entry for entry in os.scandir('.') if entry.is_file()]

ध्यान दें कि संस्करण 3.5 के बजाय का os.walk()उपयोग करता है , और इसकी गति पीईपी 471 के अनुसार 2-20 गुना बढ़ गई है ।os.scandir()os.listdir()

मुझे भी नीचे ShadowRanger की टिप्पणी पढ़ने की सलाह देते हैं।


1
धन्यवाद! मुझे लगता है कि यह एकमात्र समाधान है जो सीधे नहीं लौट रहा है list। यदि p.nameपहले pपसंद हो तो वैकल्पिक रूप से उपयोग कर सकते हैं ।
जेरोमज

1
स्वागत हे! मैं pathlib.Path()उदाहरण प्रस्तुत करना पसंद करूंगा क्योंकि उनके पास कई उपयोगी तरीके हैं जो मैं बर्बाद नहीं करना चाहता हूं। आप str(p)उन्हें पथ नामों के लिए भी कॉल कर सकते हैं ।
ज़ीबेथआदम जूड

6
नोट: os.scandirसमाधान os.listdirएक os.path.is_fileचेक या जैसे की तुलना में अधिक कुशल होने जा रहा है , भले ही आपको आवश्यकता हो list(ताकि आपको आलसी पुनरावृत्ति से लाभ न हो), क्योंकि os.scandirओएस प्रदान की गई एपीआई का उपयोग करता है जो आपको is_fileमुफ्त में सूचना देता है जैसे कि यह पुनरावृत्त करता है। , करने के लिए डिस्क पर कोई प्रति-फ़ाइल राउंड ट्रिप statसब पर उन्हें (Windows पर, DirEntryरों आप पूरा मिल statमुक्त करने के लिए जानकारी, * NIX सिस्टम पर यह करने की जरूरत statकी जानकारी परे के लिए is_file, is_dir, आदि, लेकिन DirEntryपहले पर कैश statसुविधा के लिए)।
शैडो रेंजर

1
आप entry.nameकेवल फ़ाइल नाम entry.pathप्राप्त करने के लिए या इसका पूर्ण पथ प्राप्त करने के लिए भी उपयोग कर सकते हैं । कोई और अधिक ओ.एस.पी.पाथ नहीं है।
user136036

56

प्रारंभिक नोट्स

  • हालाँकि फ़ाइल और निर्देशिका के बीच एक स्पष्ट अंतर है प्रश्न पाठ में शर्तों के , लेकिन कुछ यह तर्क दे सकते हैं कि निर्देशिका वास्तव में विशेष फाइलें हैं
  • बयान: " एक निर्देशिका की सभी फाइलें " दो तरीकों से व्याख्या की जा सकती हैं:
    1. सभी प्रत्यक्ष (या स्तर 1) वंशज ही
    2. पूरी निर्देशिका ट्री में सभी वंशज (उप-निर्देशिकाओं में शामिल हैं)
  • जब प्रश्न पूछा गया, तो मुझे लगता है कि पायथन 2 , एलटीएस संस्करण था, हालांकि कोड के नमूने पायथन 3 ( -5 ) द्वारा चलाए जाएंगे (मैं उन्हें संभव के रूप में पायथन 2 के अनुरूप रखूंगा ; साथ ही, किसी भी कोड से संबंधित। अजगर जिसे मैं पोस्ट करने जा रहा हूं, वह v3.5.4 से है - जब तक कि अन्यथा निर्दिष्ट न हो)। इस प्रश्न में किसी अन्य कीवर्ड से संबंधित परिणाम हैं: " उन्हें सूची में जोड़ें ":

    • प्री पायथन 2.2 में संस्करणों में, अनुक्रम (पुनरावृत्त) को अधिकतर सूचियों (टुपल्स, सेट, ...) द्वारा दर्शाया गया था।
    • में अजगर 2.2 , की अवधारणा जनरेटर ( [Python.Wiki]: जेनरेटर ) - के सौजन्य [अजगर 3]: उपज बयान ) - पेश किया गया था। समय बीतने के साथ, जेनरेटर समकक्षों ने उन कार्यों के लिए प्रकट होना शुरू कर दिया जो सूचियों के साथ काम करते थे / काम करते थे
    • में अजगर 3 , जनरेटर डिफ़ॉल्ट व्यवहार है
    • सुनिश्चित नहीं है कि सूची वापस करना अभी भी अनिवार्य है (या एक जनरेटर भी करेगा), लेकिन सूची निर्माणकर्ता को एक जनरेटर पारित करने से , इसमें से एक सूची तैयार होगी (और इसका उपभोग भी करें)। नीचे दिया गया उदाहरण [पायथन 3] के अंतरों को दर्शाता है : मानचित्र ( कार्य, पुनरावृत्ति, ... )
    >>> import sys
    >>> sys.version
    '2.7.10 (default, Mar  8 2016, 15:02:46) [MSC v.1600 64 bit (AMD64)]'
    >>> m = map(lambda x: x, [1, 2, 3])  # Just a dummy lambda function
    >>> m, type(m)
    ([1, 2, 3], <type 'list'>)
    >>> len(m)
    3


    >>> import sys
    >>> sys.version
    '3.5.4 (v3.5.4:3f56838, Aug  8 2017, 02:17:05) [MSC v.1900 64 bit (AMD64)]'
    >>> m = map(lambda x: x, [1, 2, 3])
    >>> m, type(m)
    (<map object at 0x000001B4257342B0>, <class 'map'>)
    >>> len(m)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: object of type 'map' has no len()
    >>> lm0 = list(m)  # Build a list from the generator
    >>> lm0, type(lm0)
    ([1, 2, 3], <class 'list'>)
    >>>
    >>> lm1 = list(m)  # Build a list from the same generator
    >>> lm1, type(lm1)  # Empty list now - generator already consumed
    ([], <class 'list'>)
  • उदाहरण निम्नलिखित संरचना के साथ root_dir नामक निर्देशिका पर आधारित होंगे (यह उदाहरण विन के लिए है , लेकिन मैं Lnx पर भी उसी पेड़ का उपयोग कर रहा हूं ):

    E:\Work\Dev\StackOverflow\q003207219>tree /f "root_dir"
    Folder PATH listing for volume Work
    Volume serial number is 00000029 3655:6FED
    E:\WORK\DEV\STACKOVERFLOW\Q003207219\ROOT_DIR
    ¦   file0
    ¦   file1
    ¦
    +---dir0
    ¦   +---dir00
    ¦   ¦   ¦   file000
    ¦   ¦   ¦
    ¦   ¦   +---dir000
    ¦   ¦           file0000
    ¦   ¦
    ¦   +---dir01
    ¦   ¦       file010
    ¦   ¦       file011
    ¦   ¦
    ¦   +---dir02
    ¦       +---dir020
    ¦           +---dir0200
    +---dir1
    ¦       file10
    ¦       file11
    ¦       file12
    ¦
    +---dir2
    ¦   ¦   file20
    ¦   ¦
    ¦   +---dir20
    ¦           file200
    ¦
    +---dir3


समाधान

प्रोग्रामेटिक दृष्टिकोण:

  1. [अजगर 3]: ओएस। listdir ( पथ = '।' )

    पथ द्वारा दी गई निर्देशिका में प्रविष्टियों के नाम वाली सूची लौटाएं। सूची मनमाने क्रम में है, और इसमें विशेष प्रविष्टियाँ '.'और शामिल नहीं हैं '..'...


    >>> import os
    >>> root_dir = "root_dir"  # Path relative to current dir (os.getcwd())
    >>>
    >>> os.listdir(root_dir)  # List all the items in root_dir
    ['dir0', 'dir1', 'dir2', 'dir3', 'file0', 'file1']
    >>>
    >>> [item for item in os.listdir(root_dir) if os.path.isfile(os.path.join(root_dir, item))]  # Filter items and only keep files (strip out directories)
    ['file0', 'file1']

    एक अधिक विस्तृत उदाहरण ( code_os_listdir.py ):

    import os
    from pprint import pformat
    
    
    def _get_dir_content(path, include_folders, recursive):
        entries = os.listdir(path)
        for entry in entries:
            entry_with_path = os.path.join(path, entry)
            if os.path.isdir(entry_with_path):
                if include_folders:
                    yield entry_with_path
                if recursive:
                    for sub_entry in _get_dir_content(entry_with_path, include_folders, recursive):
                        yield sub_entry
            else:
                yield entry_with_path
    
    
    def get_dir_content(path, include_folders=True, recursive=True, prepend_folder_name=True):
        path_len = len(path) + len(os.path.sep)
        for item in _get_dir_content(path, include_folders, recursive):
            yield item if prepend_folder_name else item[path_len:]
    
    
    def _get_dir_content_old(path, include_folders, recursive):
        entries = os.listdir(path)
        ret = list()
        for entry in entries:
            entry_with_path = os.path.join(path, entry)
            if os.path.isdir(entry_with_path):
                if include_folders:
                    ret.append(entry_with_path)
                if recursive:
                    ret.extend(_get_dir_content_old(entry_with_path, include_folders, recursive))
            else:
                ret.append(entry_with_path)
        return ret
    
    
    def get_dir_content_old(path, include_folders=True, recursive=True, prepend_folder_name=True):
        path_len = len(path) + len(os.path.sep)
        return [item if prepend_folder_name else item[path_len:] for item in _get_dir_content_old(path, include_folders, recursive)]
    
    
    def main():
        root_dir = "root_dir"
        ret0 = get_dir_content(root_dir, include_folders=True, recursive=True, prepend_folder_name=True)
        lret0 = list(ret0)
        print(ret0, len(lret0), pformat(lret0))
        ret1 = get_dir_content_old(root_dir, include_folders=False, recursive=True, prepend_folder_name=False)
        print(len(ret1), pformat(ret1))
    
    
    if __name__ == "__main__":
        main()

    नोट :

    • दो कार्यान्वयन हैं:
      • एक जो जनरेटर का उपयोग करता है (निश्चित रूप से यहां यह बेकार लगता है, क्योंकि मैं तुरंत परिणाम को सूची में बदल देता हूं)
      • क्लासिक वन ( _old में समाप्त होने वाले फ़ंक्शन नाम )
    • पुनरावर्तन का उपयोग किया जाता है (उपनिर्देशिका में जाने के लिए)
    • प्रत्येक कार्यान्वयन के लिए दो कार्य हैं:
      • एक जो एक अंडरस्कोर ( _ ) से शुरू होता है : "निजी" (इसे सीधे नहीं कहा जाना चाहिए) - जो सभी काम करता है
      • सार्वजनिक एक (पिछले से अधिक आवरण): यह लौटी प्रविष्टियों से प्रारंभिक पथ (यदि आवश्यक हो) को हटा देता है। यह एक बदसूरत कार्यान्वयन है, लेकिन यह एकमात्र विचार है कि मैं इस बिंदु पर आ सकता हूं
    • प्रदर्शन के संदर्भ में, जनरेटर आमतौर पर थोड़ा तेज होते हैं ( निर्माण और पुनरावृत्ति दोनों पर विचार करते हुए) समय को देखते हुए), लेकिन मैंने उन्हें पुनरावर्ती कार्यों में परीक्षण नहीं किया, और यह भी कि मैं आंतरिक जनरेटर पर फ़ंक्शन के अंदर पुनरावृत्ति कर रहा हूं - प्रदर्शन कैसा है मित्रवत है
    • विभिन्न परिणामों को प्राप्त करने के लिए तर्कों के साथ खेलें


    आउटपुट :

    (py35x64_test) E:\Work\Dev\StackOverflow\q003207219>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" "code_os_listdir.py"
    <generator object get_dir_content at 0x000001BDDBB3DF10> 22 ['root_dir\\dir0',
     'root_dir\\dir0\\dir00',
     'root_dir\\dir0\\dir00\\dir000',
     'root_dir\\dir0\\dir00\\dir000\\file0000',
     'root_dir\\dir0\\dir00\\file000',
     'root_dir\\dir0\\dir01',
     'root_dir\\dir0\\dir01\\file010',
     'root_dir\\dir0\\dir01\\file011',
     'root_dir\\dir0\\dir02',
     'root_dir\\dir0\\dir02\\dir020',
     'root_dir\\dir0\\dir02\\dir020\\dir0200',
     'root_dir\\dir1',
     'root_dir\\dir1\\file10',
     'root_dir\\dir1\\file11',
     'root_dir\\dir1\\file12',
     'root_dir\\dir2',
     'root_dir\\dir2\\dir20',
     'root_dir\\dir2\\dir20\\file200',
     'root_dir\\dir2\\file20',
     'root_dir\\dir3',
     'root_dir\\file0',
     'root_dir\\file1']
    11 ['dir0\\dir00\\dir000\\file0000',
     'dir0\\dir00\\file000',
     'dir0\\dir01\\file010',
     'dir0\\dir01\\file011',
     'dir1\\file10',
     'dir1\\file11',
     'dir1\\file12',
     'dir2\\dir20\\file200',
     'dir2\\file20',
     'file0',
     'file1']


  1. [अजगर 3]: ओएस। स्कैंडिर ( पथ = '।' ) ( पायथन 3.5 +, बैकपोर्ट: [PyPI]: स्कैंडिर )

    पथ द्वारा दी गई निर्देशिका में प्रविष्टियों के अनुरूप os.DirEntry वस्तुओं का एक पुनरावर्तक लौटें । प्रविष्टियों मनमाना क्रम में सामने आए हैं, और विशेष प्रविष्टियों और शामिल नहीं हैं।'.''..'

    का उपयोग करते हुए scandir () के बजाय listdir () भी महत्वपूर्ण है, कोड है कि यह भी फ़ाइल प्रकार या फ़ाइल विशेषता जानकारी की जरूरत के प्रदर्शन को बेहतर कर सकते हैं क्योंकि os.DirEntry वस्तुओं इस जानकारी का खुलासा जब एक निर्देशिका स्कैन करता है, तो ऑपरेटिंग सिस्टम यह प्रदान करता है। सभी os.DirEntry विधियाँ एक सिस्टम कॉल कर सकती हैं, लेकिन is_dir () और is_file () में आमतौर पर केवल प्रतीकात्मक लिंक के लिए सिस्टम कॉल की आवश्यकता होती है; os.DirEntry.stat () को हमेशा यूनिक्स पर एक सिस्टम कॉल की आवश्यकता होती है, लेकिन केवल विंडोज पर प्रतीकात्मक लिंक के लिए एक की आवश्यकता होती है।


    >>> import os
    >>> root_dir = os.path.join(".", "root_dir")  # Explicitly prepending current directory
    >>> root_dir
    '.\\root_dir'
    >>>
    >>> scandir_iterator = os.scandir(root_dir)
    >>> scandir_iterator
    <nt.ScandirIterator object at 0x00000268CF4BC140>
    >>> [item.path for item in scandir_iterator]
    ['.\\root_dir\\dir0', '.\\root_dir\\dir1', '.\\root_dir\\dir2', '.\\root_dir\\dir3', '.\\root_dir\\file0', '.\\root_dir\\file1']
    >>>
    >>> [item.path for item in scandir_iterator]  # Will yield an empty list as it was consumed by previous iteration (automatically performed by the list comprehension)
    []
    >>>
    >>> scandir_iterator = os.scandir(root_dir)  # Reinitialize the generator
    >>> for item in scandir_iterator :
    ...     if os.path.isfile(item.path):
    ...             print(item.name)
    ...
    file0
    file1

    नोट :

    • के समान है os.listdir
    • लेकिन यह अधिक लचीला है (और अधिक कार्यक्षमता प्रदान करता है), अधिक पायथन आईसी (और कुछ मामलों में, तेज)


  1. [अजगर 3]: ओएस। वॉक ( शीर्ष, टॉपडाउन = ट्रू, ऑनरोर = कोई नहीं, अनुवर्ती = गलत )

    किसी ट्री में ट्री के नाम को ऊपर-नीचे या नीचे-ऊपर ट्री को चलाकर उत्पन्न करें। पेड़ निर्देशिका में निहित में प्रत्येक निर्देशिका के लिए शीर्ष (सहित शीर्ष ही), यह एक 3-टपल पैदावार ( dirpath, dirnames, filenames)।


    >>> import os
    >>> root_dir = os.path.join(os.getcwd(), "root_dir")  # Specify the full path
    >>> root_dir
    'E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir'
    >>>
    >>> walk_generator = os.walk(root_dir)
    >>> root_dir_entry = next(walk_generator)  # First entry corresponds to the root dir (passed as an argument)
    >>> root_dir_entry
    ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir', ['dir0', 'dir1', 'dir2', 'dir3'], ['file0', 'file1'])
    >>>
    >>> root_dir_entry[1] + root_dir_entry[2]  # Display dirs and files (direct descendants) in a single list
    ['dir0', 'dir1', 'dir2', 'dir3', 'file0', 'file1']
    >>>
    >>> [os.path.join(root_dir_entry[0], item) for item in root_dir_entry[1] + root_dir_entry[2]]  # Display all the entries in the previous list by their full path
    ['E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir0', 'E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir1', 'E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir2', 'E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir3', 'E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\file0', 'E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\file1']
    >>>
    >>> for entry in walk_generator:  # Display the rest of the elements (corresponding to every subdir)
    ...     print(entry)
    ...
    ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir0', ['dir00', 'dir01', 'dir02'], [])
    ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir0\\dir00', ['dir000'], ['file000'])
    ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir0\\dir00\\dir000', [], ['file0000'])
    ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir0\\dir01', [], ['file010', 'file011'])
    ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir0\\dir02', ['dir020'], [])
    ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir0\\dir02\\dir020', ['dir0200'], [])
    ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir0\\dir02\\dir020\\dir0200', [], [])
    ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir1', [], ['file10', 'file11', 'file12'])
    ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir2', ['dir20'], ['file20'])
    ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir2\\dir20', [], ['file200'])
    ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir3', [], [])

    नोट :

    • दृश्यों के तहत, इसका उपयोग os.scandir( os.listdirपुराने संस्करणों पर)
    • यह सबफ़ोल्डर्स में आवर्ती द्वारा भारी उठाने का काम करता है


  1. [अजगर 3]: ग्लोब। ग्लोब ( पथनाम, *, पुनरावर्ती = गलत ) ( [पायथन 3]: ग्लोब। इग्लोब ( पथनाम, *, पुनरावर्ती = गलत ) )

    पथनाम से मेल खाने वाले पथ नामों की संभवतः-रिक्त सूची लौटाएं , जिसमें पथ विनिर्देश युक्त स्ट्रिंग होना चाहिए। पाथनाम या तो निरपेक्ष (जैसे /usr/src/Python-1.5/Makefile) या रिश्तेदार (जैसे ../../Tools/*/*.gif) हो सकते हैं, और शेल-स्टाइल वाइल्डकार्ड हो सकते हैं। टूटे हुए सिमलिंक परिणामों में शामिल हैं (शेल में)।
    ...
    संस्करण 3.5 में बदला : " **" का उपयोग करते हुए पुनरावर्ती ग्लब्स के लिए समर्थन ।


    >>> import glob, os
    >>> wildcard_pattern = "*"
    >>> root_dir = os.path.join("root_dir", wildcard_pattern)  # Match every file/dir name
    >>> root_dir
    'root_dir\\*'
    >>>
    >>> glob_list = glob.glob(root_dir)
    >>> glob_list
    ['root_dir\\dir0', 'root_dir\\dir1', 'root_dir\\dir2', 'root_dir\\dir3', 'root_dir\\file0', 'root_dir\\file1']
    >>>
    >>> [item.replace("root_dir" + os.path.sep, "") for item in glob_list]  # Strip the dir name and the path separator from begining
    ['dir0', 'dir1', 'dir2', 'dir3', 'file0', 'file1']
    >>>
    >>> for entry in glob.iglob(root_dir + "*", recursive=True):
    ...     print(entry)
    ...
    root_dir\
    root_dir\dir0
    root_dir\dir0\dir00
    root_dir\dir0\dir00\dir000
    root_dir\dir0\dir00\dir000\file0000
    root_dir\dir0\dir00\file000
    root_dir\dir0\dir01
    root_dir\dir0\dir01\file010
    root_dir\dir0\dir01\file011
    root_dir\dir0\dir02
    root_dir\dir0\dir02\dir020
    root_dir\dir0\dir02\dir020\dir0200
    root_dir\dir1
    root_dir\dir1\file10
    root_dir\dir1\file11
    root_dir\dir1\file12
    root_dir\dir2
    root_dir\dir2\dir20
    root_dir\dir2\dir20\file200
    root_dir\dir2\file20
    root_dir\dir3
    root_dir\file0
    root_dir\file1

    नोट :

    • उपयोग os.listdir
    • बड़े पेड़ों के लिए (खासकर अगर पुनरावर्ती चालू है), इग्लोब को प्राथमिकता दी जाती है
    • नाम के आधार पर (वाइल्डकार्ड के कारण) उन्नत फ़िल्टरिंग की अनुमति देता है


  1. [पायथन 3]: क्लास पाथलिब। पथ ( * रास्ते ) ( पायथन 3.4 +, बैकपोर्ट: [PyPI]: pathlib2 )

    >>> import pathlib
    >>> root_dir = "root_dir"
    >>> root_dir_instance = pathlib.Path(root_dir)
    >>> root_dir_instance
    WindowsPath('root_dir')
    >>> root_dir_instance.name
    'root_dir'
    >>> root_dir_instance.is_dir()
    True
    >>>
    >>> [item.name for item in root_dir_instance.glob("*")]  # Wildcard searching for all direct descendants
    ['dir0', 'dir1', 'dir2', 'dir3', 'file0', 'file1']
    >>>
    >>> [os.path.join(item.parent.name, item.name) for item in root_dir_instance.glob("*") if not item.is_dir()]  # Display paths (including parent) for files only
    ['root_dir\\file0', 'root_dir\\file1']

    नोट :

    • यह हमारे लक्ष्य को प्राप्त करने का एक तरीका है
    • यह रास्तों को संभालने की OOP शैली है
    • बहुत सारी कार्यक्षमता प्रदान करता है


  1. [अजगर 2]: dircache.listdir (पथ) ( केवल पायथन 2 )


    def listdir(path):
        """List directory contents, using cache."""
        try:
            cached_mtime, list = cache[path]
            del cache[path]
        except KeyError:
            cached_mtime, list = -1, []
        mtime = os.stat(path).st_mtime
        if mtime != cached_mtime:
            list = os.listdir(path)
            list.sort()
        cache[path] = mtime, list
        return list


  1. [man7]: OPENDIR (3) / [man7]: READDIR (3) / [man7]: CLOSEDIR (3) के माध्यम से [अजगर 3]: ctypes - Pyon के लिए एक विदेशी फ़ंक्शन लाइब्रेरी ( POSIX विशिष्ट)

    ctypes अजगर के लिए एक विदेशी फ़ंक्शन लाइब्रेरी है। यह सी संगत डेटा प्रकार प्रदान करता है, और DLL या साझा पुस्तकालयों में कॉलिंग फ़ंक्शन की अनुमति देता है। इसका उपयोग इन पुस्तकालयों को शुद्ध पायथन में लपेटने के लिए किया जा सकता है।

    code_ctypes.py :

    #!/usr/bin/env python3
    
    import sys
    from ctypes import Structure, \
        c_ulonglong, c_longlong, c_ushort, c_ubyte, c_char, c_int, \
        CDLL, POINTER, \
        create_string_buffer, get_errno, set_errno, cast
    
    
    DT_DIR = 4
    DT_REG = 8
    
    char256 = c_char * 256
    
    
    class LinuxDirent64(Structure):
        _fields_ = [
            ("d_ino", c_ulonglong),
            ("d_off", c_longlong),
            ("d_reclen", c_ushort),
            ("d_type", c_ubyte),
            ("d_name", char256),
        ]
    
    LinuxDirent64Ptr = POINTER(LinuxDirent64)
    
    libc_dll = this_process = CDLL(None, use_errno=True)
    # ALWAYS set argtypes and restype for functions, otherwise it's UB!!!
    opendir = libc_dll.opendir
    readdir = libc_dll.readdir
    closedir = libc_dll.closedir
    
    
    def get_dir_content(path):
        ret = [path, list(), list()]
        dir_stream = opendir(create_string_buffer(path.encode()))
        if (dir_stream == 0):
            print("opendir returned NULL (errno: {:d})".format(get_errno()))
            return ret
        set_errno(0)
        dirent_addr = readdir(dir_stream)
        while dirent_addr:
            dirent_ptr = cast(dirent_addr, LinuxDirent64Ptr)
            dirent = dirent_ptr.contents
            name = dirent.d_name.decode()
            if dirent.d_type & DT_DIR:
                if name not in (".", ".."):
                    ret[1].append(name)
            elif dirent.d_type & DT_REG:
                ret[2].append(name)
            dirent_addr = readdir(dir_stream)
        if get_errno():
            print("readdir returned NULL (errno: {:d})".format(get_errno()))
        closedir(dir_stream)
        return ret
    
    
    def main():
        print("{:s} on {:s}\n".format(sys.version, sys.platform))
        root_dir = "root_dir"
        entries = get_dir_content(root_dir)
        print(entries)
    
    
    if __name__ == "__main__":
        main()

    नोट :

    • यह तीन कार्यों को libc (वर्तमान प्रक्रिया में लोड) से लोड करता है और उन्हें कॉल करता है (अधिक विवरण के लिए जांच करें [SO]: मैं यह कैसे जांचूं कि क्या कोई फ़ाइल अपवाद के बिना मौजूद है? (@ CristiFati का जवाब) - आइटम # 4 से अंतिम नोट्स )। इस दृष्टिकोण को पायथन / सी किनारे के बहुत करीब रखा जाएगा
    • LinuxDirent64 है ctypes के प्रतिनिधित्व struct dirent64 से [आदमी है 7]: dirent.h (0p) (ताकि हैं DT_ मेरी मशीन से स्थिरांक): Ubtu 16 64 ( 4.10.0-40-सामान्य और libc6-देव: amd64 )। अन्य स्वादों / संस्करणों पर, संरचनात्मक परिभाषा भिन्न हो सकती है, और यदि हां, तो ctypes उपनाम को अपडेट किया जाना चाहिए, अन्यथा यह अपरिभाषित व्यवहार का उत्पादन करेगा
    • यह os.walkप्रारूप में डेटा लौटाता है । मैंने इसे पुनरावर्ती बनाने की जहमत नहीं उठाई, लेकिन मौजूदा कोड से शुरू करते हुए, यह काफी तुच्छ कार्य होगा
    • सब कुछ पर संभव है जीत के साथ-साथ, डेटा (पुस्तकालयों, काम करता है, structs, स्थिरांक, ...) अलग


    आउटपुट :

    [cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q003207219]> ./code_ctypes.py
    3.5.2 (default, Nov 12 2018, 13:43:14)
    [GCC 5.4.0 20160609] on linux
    
    ['root_dir', ['dir2', 'dir1', 'dir3', 'dir0'], ['file1', 'file0']]


  1. [ActiveState.Docs]: win32file.FindFilesW ( विन विशिष्ट)

    विंडोज यूनिकोड एपीआई का उपयोग करके, मिलान फ़ाइल नाम की एक सूची प्राप्त करता है। एपीआई FindFirstFileW / FindNextFileW / करीब कार्यों का पता लगाने के लिए एक इंटरफ़ेस।


    >>> import os, win32file, win32con
    >>> root_dir = "root_dir"
    >>> wildcard = "*"
    >>> root_dir_wildcard = os.path.join(root_dir, wildcard)
    >>> entry_list = win32file.FindFilesW(root_dir_wildcard)
    >>> len(entry_list)  # Don't display the whole content as it's too long
    8
    >>> [entry[-2] for entry in entry_list]  # Only display the entry names
    ['.', '..', 'dir0', 'dir1', 'dir2', 'dir3', 'file0', 'file1']
    >>>
    >>> [entry[-2] for entry in entry_list if entry[0] & win32con.FILE_ATTRIBUTE_DIRECTORY and entry[-2] not in (".", "..")]  # Filter entries and only display dir names (except self and parent)
    ['dir0', 'dir1', 'dir2', 'dir3']
    >>>
    >>> [os.path.join(root_dir, entry[-2]) for entry in entry_list if entry[0] & (win32con.FILE_ATTRIBUTE_NORMAL | win32con.FILE_ATTRIBUTE_ARCHIVE)]  # Only display file "full" names
    ['root_dir\\file0', 'root_dir\\file1']

    नोट :


  1. कुछ (अन्य) तृतीय-पक्ष पैकेज स्थापित करें जो चाल करता है
    • सबसे अधिक संभावना है, ऊपर के एक (या अधिक) पर भरोसा करेगा (शायद मामूली अनुकूलन के साथ)


नोट :

  • कोड पोर्टेबल होने का मतलब है (एक विशिष्ट क्षेत्र को लक्षित करने वाले स्थानों को छोड़कर - जो चिह्नित हैं) या क्रॉस:

    • मंच ( निक्स , विन ,)
    • पायथन संस्करण (2, 3,)
  • कई प्रकार की शैलियों (पूर्ण, रिश्तेदार) का उपयोग उपरोक्त वेरिएंट में किया गया था, इस तथ्य का वर्णन करने के लिए कि इस दिशा में "उपकरण" का उपयोग लचीला है

  • os.listdirऔर os.scandirउपयोग opendir / readdir / closedir ( [MS.Docs]: FindFirstFileW समारोह / [MS.Docs]: FindNextFileW समारोह / [MS.Docs]: FindClose समारोह ) (के माध्यम से [GitHub]: अजगर / CPython - (गुरु) CPython / मॉड्यूल / posixmodule.c )

  • win32file.FindFilesWउन ( विन विशिष्ट) कार्यों का उपयोग करता है ( GitHub के माध्यम से ): mhammond / pywin32 - (मास्टर) pywin32 / win32 / src / win32file.i )

  • _get_dir_content (बिंदु # 1 से ) इनमें से किसी भी दृष्टिकोण का उपयोग करके लागू किया जा सकता है (कुछ को अधिक काम करने की आवश्यकता होगी और कुछ को कुछ)

    • कुछ उन्नत फ़िल्टरिंग (केवल फ़ाइल बनाम डीआईआर के बजाय ) किया जा सकता है: उदाहरण के लिए शामिल_फॉल्डर्स तर्क को एक दूसरे से बदला जा सकता है (जैसे फ़िल्टर_फंक ) जो एक फ़ंक्शन होगा जो एक तर्क के रूप में एक रास्ता लेता है: filter_func=lambda x: True(यह पट्टी नहीं करता है) कुछ भी) और अंदर _get_dir_content कुछ ऐसा है: if not filter_func(entry_with_path): continue(यदि फ़ंक्शन एक प्रविष्टि के लिए विफल रहता है, तो इसे छोड़ दिया जाएगा), लेकिन कोड जितना अधिक जटिल हो जाएगा, इसे निष्पादित करने में अधिक समय लगेगा।
  • नोटा बेने! चूंकि पुनरावर्तन का उपयोग किया जाता है, इसलिए मुझे यह उल्लेख करना चाहिए कि मैंने अपने लैपटॉप पर कुछ परीक्षण किए ( विन 10 x64 ), इस समस्या से पूरी तरह से असंबंधित है, और जब पुनरावृत्ति का स्तर (990 .. 1000) सीमा ( पुनरावर्ती नाम ) - 1000 में कहीं मूल्यों तक पहुंच रहा था (डिफ़ॉल्ट)), मुझे StackOverflow :) मिला । यदि निर्देशिका ट्री उस सीमा से अधिक है (मैं एक FS विशेषज्ञ नहीं हूं, तो मुझे नहीं पता कि यदि यह संभव भी है), तो यह एक समस्या हो सकती है।
    मुझे यह भी उल्लेख करना चाहिए कि मैंने पुनरावृत्ति को बढ़ाने की कोशिश नहीं की क्योंकि मुझे इस क्षेत्र में कोई अनुभव नहीं है (स्टैक को बढ़ाने के लिए इससे पहले कि मैं इसे कैसे बढ़ा सकता हूं ओएसस्तर), लेकिन सिद्धांत में हमेशा विफलता की संभावना होगी, अगर डीर की गहराई उच्चतम संभव पुनरावर्ती (उस मशीन पर) से बड़ी है

  • कोड नमूने केवल प्रदर्शनकारी उद्देश्यों के लिए हैं। इसका मतलब है कि कि मैं खाता गलती से निपटने में नहीं लिया (मैं वहाँ किसी भी नहीं लगता कि कोशिश / छोड़कर / किसी और / अंत में इतना कोड मजबूत नहीं है ब्लॉक), (कारण है: सरल रूप में और कम संभव के रूप में इसे रखने के लिए )। के लिए उत्पादन , त्रुटि हैंडलिंग में अच्छी तरह से जोड़ा जाना चाहिए

अन्य दृष्टिकोण:

  1. पायथन का उपयोग केवल एक आवरण के रूप में करें

    • सब कुछ एक और तकनीक का उपयोग करके किया जाता है
    • वह तकनीक अजगर से मंगाई गई है
    • सबसे प्रसिद्ध स्वाद जो मुझे पता है कि मैं सिस्टम प्रशासक दृष्टिकोण को क्या कहता हूं :

      • उपयोग अजगर (या उस बात के लिए किसी भी प्रोग्रामिंग भाषा) आदेश पर अमल करने में खोल आदेश (और उनके outputs पार्स)
      • कुछ इसे साफ-सुथरी हैक मानते हैं
      • मैं इसे एक लंगड़ा वर्कअराउंड ( गेनरी ) की तरह अधिक मानता हूं , क्योंकि प्रति सेक्शन शेल ( इस मामले में cmd ) से किया जाता है, और इस तरह इसका पायथन से कोई लेना-देना नहीं है ।
      • फ़िल्टरिंग ( grep/ findstr) या आउटपुट स्वरूपण दोनों पक्षों पर किया जा सकता है, लेकिन मैं इस पर जोर नहीं देने जा रहा हूं। इसके अलावा, मैं जानबूझकर के os.systemबजाय इस्तेमाल किया subprocess.Popen
      (py35x64_test) E:\Work\Dev\StackOverflow\q003207219>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" -c "import os;os.system(\"dir /b root_dir\")"
      dir0
      dir1
      dir2
      dir3
      file0
      file1

    सामान्य तौर पर इस दृष्टिकोण से बचा जाना चाहिए, क्योंकि अगर कुछ कमांड आउटपुट प्रारूप ओएस संस्करणों / स्वादों के बीच थोड़ा भिन्न होता है, तो पार्सिंग कोड को भी अनुकूलित किया जाना चाहिए; स्थानों के बीच अंतर का उल्लेख नहीं करना)।


48

मुझे वास्तव में adamk का उत्तर पसंद आया , यह सुझाव देते हुए कि आप glob()उसी नाम के मॉड्यूल से उपयोग करते हैं । यह आपको *एस के साथ मिलान करने की अनुमति देता है ।

लेकिन जैसा कि अन्य लोगों ने टिप्पणी में बताया है, glob()असंगत स्लैश दिशाओं पर फंस सकता है। इसके साथ मदद करने के लिए, मेरा सुझाव है कि आप मॉड्यूल में join()और expanduser()फ़ंक्शन का उपयोग करें os.path, और शायद मॉड्यूल getcwd()में फ़ंक्शन osभी।

उदाहरण के रूप में:

from glob import glob

# Return everything under C:\Users\admin that contains a folder called wlp.
glob('C:\Users\admin\*\wlp')

उपरोक्त भयानक है - पथ हार्डकोड किया गया है और केवल ड्राइव नाम और \पथ में हार्डकोड किया जा रहा है के बीच विंडोज पर कभी काम करेगा ।

from glob    import glob
from os.path import join

# Return everything under Users, admin, that contains a folder called wlp.
glob(join('Users', 'admin', '*', 'wlp'))

उपरोक्त बेहतर काम करता है, लेकिन यह फ़ोल्डर के नाम पर निर्भर करता है Usersजो अक्सर विंडोज पर पाया जाता है और ऐसा अक्सर अन्य ओएस पर नहीं मिलता है। यह भी एक विशिष्ट नाम होने उपयोगकर्ता पर निर्भर करता है admin

from glob    import glob
from os.path import expanduser, join

# Return everything under the user directory that contains a folder called wlp.
glob(join(expanduser('~'), '*', 'wlp'))

यह सभी प्लेटफार्मों पर पूरी तरह से काम करता है।

एक और बढ़िया उदाहरण जो प्लेटफ़ॉर्म पर पूरी तरह से काम करता है और कुछ अलग करता है:

from glob    import glob
from os      import getcwd
from os.path import join

# Return everything under the current directory that contains a folder called wlp.
glob(join(getcwd(), '*', 'wlp'))

आशा है कि ये उदाहरण आपको उन कुछ कार्यों की शक्ति को देखने में मदद करेंगे जो आप मानक पायथन लाइब्रेरी मॉड्यूल में पा सकते हैं।


4
अतिरिक्त ग्लोब फन: पायथन 3.5 में शुरू, **जब तक आप सेट करते हैं , तब तक काम करता है recursive = True। यहाँ डॉक्स देखें: docs.python.org/3.5/library/glob.html#glob.glob
ArtOfWarfare

35
def list_files(path):
    # returns a list of names (with extension, without full path) of all files 
    # in folder path
    files = []
    for name in os.listdir(path):
        if os.path.isfile(os.path.join(path, name)):
            files.append(name)
    return files 

23

यदि आप एक पायथन कार्यान्वयन के लिए देख रहे हैं तलाश हैं , तो यह एक ऐसा नुस्खा है जिसका मैं अक्सर उपयोग करता हूं:

from findtools.find_files import (find_files, Match)

# Recursively find all *.sh files in **/usr/bin**
sh_files_pattern = Match(filetype='f', name='*.sh')
found_files = find_files(path='/usr/bin', match=sh_files_pattern)

for found_file in found_files:
    print found_file

इसलिए मैंने इसमें से एक PyPI पैकेज बनाया और एक GitHub रिपॉजिटरी भी है । मुझे उम्मीद है कि किसी को यह इस कोड के लिए संभावित रूप से उपयोगी लगता है।


14

अधिक परिणामों के लिए, आप की listdir()विधि का उपयोग कर सकते हैंos एक जनरेटर के साथ-साथ मॉड्यूल (एक जनरेटर एक शक्तिशाली पुनरावृत्ति है जो अपनी स्थिति रखता है, याद रखें?)। निम्नलिखित कोड दोनों संस्करणों के साथ ठीक काम करता है: पायथन 2 और पायथन 3।

यहाँ एक कोड है:

import os

def files(path):  
    for file in os.listdir(path):
        if os.path.isfile(os.path.join(path, file)):
            yield file

for file in files("."):  
    print (file)

listdir()विधि दी निर्देशिका के लिए प्रविष्टियों की सूची देता है। यदि दी गई प्रविष्टि एक फ़ाइल है तो विधि os.path.isfile()वापस आ Trueजाती है। और yieldऑपरेटर फंक को छोड़ देता है लेकिन अपनी वर्तमान स्थिति को बनाए रखता है, और यह केवल फ़ाइल के रूप में पाई गई प्रविष्टि का नाम देता है। उपरोक्त सभी हमें जनरेटर फ़ंक्शन पर लूप करने की अनुमति देता है।


11

निरपेक्ष फ़ाइलपथ की सूची लौटाते हुए, उपनिर्देशिकाओं में पुनरावृत्ति नहीं करता है

L = [os.path.join(os.getcwd(),f) for f in os.listdir('.') if os.path.isfile(os.path.join(os.getcwd(),f))]

2
नोट: के os.path.abspath(f)लिए कुछ सस्ता विकल्प होगा os.path.join(os.getcwd(),f)
शैडो रेंजर

मैं और अधिक कुशल अभी भी अगर आप के साथ शुरू होगा cwd = os.path.abspath('.'), तो इस्तेमाल किया cwdके बजाय '.'और os.getcwd()अनावश्यक प्रणाली कॉल की बचने के भार को भर में।
मार्टिन पीटर्स

10
import os
import os.path


def get_files(target_dir):
    item_list = os.listdir(target_dir)

    file_list = list()
    for item in item_list:
        item_dir = os.path.join(target_dir,item)
        if os.path.isdir(item_dir):
            file_list += get_files(item_dir)
        else:
            file_list.append(item_dir)
    return file_list

यहां मैं एक पुनरावर्ती संरचना का उपयोग करता हूं।


इसे केवल एक लाइन में ही प्राप्त किया जा सकता है pathlib:filter(Path.is_file, Path().rglob('*'))
जियोर्जी

9

एक बुद्धिमान शिक्षक ने मुझे एक बार कहा था:

जब कुछ करने के कई स्थापित तरीके होते हैं, तो उनमें से कोई भी सभी मामलों के लिए अच्छा नहीं होता है।

मैं इस प्रकार समस्या का एक सबसेट के लिए एक समाधान जोड़ूंगा : काफी बार, हम केवल यह जांचना चाहते हैं कि क्या फ़ाइल उप स्ट्रिंग में जाने के बिना स्टार्ट स्ट्रिंग और एंड स्ट्रिंग से मेल खाती है या नहीं। हम इस प्रकार एक फंक्शन चाहते हैं जो फ़ाइल नाम की सूची लौटाए, जैसे:

filenames = dir_filter('foo/baz', radical='radical', extension='.txt')

यदि आप पहले दो कार्यों की घोषणा करना चाहते हैं, तो यह किया जा सकता है:

def file_filter(filename, radical='', extension=''):
    "Check if a filename matches a radical and extension"
    if not filename:
        return False
    filename = filename.strip()
    return(filename.startswith(radical) and filename.endswith(extension))

def dir_filter(dirname='', radical='', extension=''):
    "Filter filenames in directory according to radical and extension"
    if not dirname:
        dirname = '.'
    return [filename for filename in os.listdir(dirname)
                if file_filter(filename, radical, extension)]

इस समाधान को नियमित अभिव्यक्तियों के साथ आसानी से सामान्यीकृत किया जा सकता है (और आप एक patternतर्क जोड़ना चाह सकते हैं , यदि आप नहीं चाहते कि आपके पैटर्न हमेशा फ़ाइल नाम के प्रारंभ या अंत से चिपके रहें)।


6

जनरेटर का उपयोग करना

import os
def get_files(search_path):
     for (dirpath, _, filenames) in os.walk(search_path):
         for filename in filenames:
             yield os.path.join(dirpath, filename)
list_files = get_files('.')
for filename in list_files:
    print(filename)

4

पायथन 3.4+ के लिए एक और बहुत पठनीय संस्करण pathlib.Path.glob का उपयोग कर रहा है:

from pathlib import Path
folder = '/foo'
[f for f in Path(folder).glob('*') if f.is_file()]

इसे और अधिक विशिष्ट बनाना सरल है, उदाहरण के लिए केवल पायथन स्रोत फ़ाइलों को देखें जो प्रतीकात्मक लिंक नहीं हैं, सभी उपनिर्देशिकाओं में भी:

[f for f in Path(folder).glob('**/*.py') if not f.is_symlink()]

3

इसके लिए यहां मेरा सामान्य उद्देश्य है। यह फ़ाइलनामों के बजाय फ़ाइल पथों की एक सूची देता है क्योंकि मैंने पाया कि यह अधिक उपयोगी है। इसके कुछ वैकल्पिक तर्क हैं जो इसे बहुमुखी बनाते हैं। उदाहरण के लिए, मैं अक्सर इसका उपयोग तर्कों जैसे pattern='*.txt'या के साथ करता हूं subfolders=True

import os
import fnmatch

def list_paths(folder='.', pattern='*', case_sensitive=False, subfolders=False):
    """Return a list of the file paths matching the pattern in the specified 
    folder, optionally including files inside subfolders.
    """
    match = fnmatch.fnmatchcase if case_sensitive else fnmatch.fnmatch
    walked = os.walk(folder) if subfolders else [next(os.walk(folder))]
    return [os.path.join(root, f)
            for root, dirnames, filenames in walked
            for f in filenames if match(f, pattern)]

2

मैं एक नमूना एक लाइनर प्रदान करूंगा, जहां sourcepath और फ़ाइल प्रकार को इनपुट के रूप में प्रदान किया जा सकता है। यह कोड सीएसवी एक्सटेंशन के साथ फाइलनाम की सूची देता है। का उपयोग करें यदि सभी फाइलों को वापस करने की आवश्यकता है। यह भी उपनिर्देशिका स्कैन करेगा।

[y for x in os.walk(sourcePath) for y in glob(os.path.join(x[0], '*.csv'))]

आवश्यकतानुसार फ़ाइल एक्सटेंशन और स्रोत पथ को संशोधित करें।


1
यदि आप उपयोग करने जा रहे हैं glob, तो बस उपयोग करें glob('**/*.csv', recursive=True)os.walk()पुनरावृत्ति के साथ इसे संयोजित करने की आवश्यकता नहीं है ( recursiveऔर **पायथन 3.5 के बाद से समर्थित हैं)।
मार्टिन पीटर्स


2

dircache "संस्करण 2.6 के बाद से पदावनत है: Python 3.0 में dircache मॉड्यूल को हटा दिया गया है।"

import dircache
list = dircache.listdir(pathname)
i = 0
check = len(list[0])
temp = []
count = len(list)
while count != 0:
  if len(list[i]) != check:
     temp.append(list[i-1])
     check = len(list[i])
  else:
    i = i + 1
    count = count - 1

print temp

17
dirchache "संस्करण 2.6 के बाद से पदावनत किया गया है: पाइथन 3.0 में dircache मॉड्यूल को हटा दिया गया है।"
डैनियल रीस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.