Питання Як перерахувати всі файли каталогу?


Як я можу перелічити всі файли каталогу в Python і додати їх до a list?


2824
2017-07-08 19:31


походження


Пов'язані з Як отримати список підкаталогу - rds
os.listdir(path) повертає список рядків імен файлів і підкаталоги з заданого шляху, або поточний, якщо пропущено. (Надайте це тут, щоб люди з Google могли бачити, тому що поточна верхня відповідь не відповідає на запитання.) - Apollys
Лише всі файли? Ви хочете перелічити підкаталоги? - Aleksandar Jovanovic
Це добре працює (найкраща відповідь нижче): from os import listdir  from os.path import isfile, join  files = [f for f in listdir(mypath) if isfile(join(mypath, f))] Примітка: вам слід призначити рядок в шлях каталогу, де зберігаються файли (наприклад: mypath = "users/name/desktop/") - Arshin
Ви маєте на увазі файли як: звичайні файли, які не є підкаталогами або посиланнями, або всі файли, включаючи підкаталоги та посилання? - Mulliganaceous


Відповіді:


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

І, нарешті, як показує цей приклад, можна додати один список до іншого .extend() або

>>> q = [1, 2, 3]
>>> w = [4, 5, 6]
>>> q = q + w
>>> q
[1, 2, 3, 4, 5, 6]

Особисто я віддаю перевагу .extend()


2828
2017-07-08 21:01



Здається, що не працює на Windows з іменами файлів Unicode з якоїсь причини. - cdiggins
Трохи простіше: (_, _, filenames) = walk(mypath).next()  (якщо ви впевнені, що прогулянка поверне принаймні одне значення, яке воно має.) - misterbee
Незначна модифікація для зберігання повних шляхів: для (dirpath, dirnames, filenames) в os.walk (mypath): checksum_files.extend (os.path.join (dirpath, filename) для імені файлу в іменах файлів) break - okigan
f.extend(filenames) насправді не є еквівалентом f = f + filenames. extend буде модифікувати f на місці, тоді як додавання створює новий список у новому місці пам'яті. Це означає extend як правило, є більш ефективним, ніж +, але іноді це може призвести до плутанини, якщо декілька об'єктів мають посилання на список. Нарешті, це варто відзначити f += filenames еквівалентно f.extend(filenames), ні  f = f + filenames. - Benjamin Hodgson♦
@ misterbee, ваше рішення найкраще, лише одне невелике вдосконалення: _, _, filenames = next(walk(mypath), (None, None, [])) - bgusach


Я вважаю за краще використовувати glob модуль, як це робить узгодження та розширення шаблону.

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

Він поверне список із запитаними файлами:

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

1142
2017-07-09 18:13



це ярлик для listdir + fnmatch docs.python.org/library/fnmatch.html#fnmatch.fnmatch - Stefano
Для мене це не додає до непослідовності, я годую його. Правильні косу риски на вході призводять до правильної косу риси на виході. - Antony Hatchkins
Я думаю, що це повинна бути прийнятою відповіддю, оскільки це найпростіша реалізація. - isosceleswheel
Остерігайтеся, що це повертає повний шлях. - xji
щоб з'ясувати, це робить ні повернути "повний шлях"; це просто повертає експансію глобуса, як би там не було. Наприклад, дано /home/user/foo/bar/hello.txt, тоді, якщо працює в каталозі foo, the glob("bar/*.txt") повернеться bar/hello.txt. Є випадки, коли ви насправді хочете повний (тобто абсолютний) шлях; для цих випадків, див stackoverflow.com/questions/51520/... - michael


import os
os.listdir("somedirectory")

поверне список всіх файлів і каталогів у "somedirectory".


520
2017-07-08 19:35



Це повертає відносний шлях файлів у порівнянні з повним шляхом, що повертається glob.glob - xji
@JIXiang: os.listdir() завжди повертається лише імена файлів (не відносні шляхи). Що glob.glob() повернення здійснюється за допомогою формату шляху вхідного шаблону. - mklement0
os.listdir () -> Завжди перелічіть dir і файл всередині передбаченого місця. Чи є який-небудь спосіб перелічити лише каталог, а не файли? - RishuA


Отримати список файлів з Python 2 і 3


Я також зробив коротке відео тут:  Python: як отримати список файлів у каталозі


os.listdir ()

або ..... жарко, щоб отримати всі файли (і каталоги) у поточному каталозі (Python 3)

Найпростішим способом мати файл у поточному каталозі в Python 3 є це. Це дуже просто; використовувати os модуль і функція listdir (), і ви матимете файл у цьому каталозі (і в кінцевому підсумку папки, що знаходяться в каталозі, але у вас не буде файлу в підкаталозі, тому що ви можете використовувати прогулянку - про це я буду говорити пізніше)

>>> import os
>>> arr = os.listdir()
>>> arr
['$RECYCLE.BIN', 'work.txt', '3ebooks.txt', 'documents']

Використання glob

Я знайшов глобус легше вибрати файл такого ж типу або з чимось спільним. Подивіться на наступний приклад:

import glob

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

Використання розуміння списку

import glob

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

Отримання повного імені шляху за допомогою os.path.abspath

Як ви помітили, у коді вище немає повного шляху до файлу. Якщо вам потрібен абсолютний шлях, ви можете використовувати іншу функцію os.path модуль називається _getfullpathname, помістивши файл, з якого ви отримуєте os.listdir() як аргумент Існують інші способи повного шляху, як ми перевіримо пізніше (я замінив, як запропонував mexmex, _getfullpathname з abspath)

>>> import os
>>> files_path = [os.path.abspath(x) for x in os.listdir()]
>>> files_path
['F:\\documenti\applications.txt', 'F:\\documenti\collections.txt']

Отримайте повне ім'я шляху типу файлу у всі підкаталоги з прогулянкою

Я вважаю це дуже корисним, щоб знайти речі в багатьох каталогах, і це допомогло мені знайти файл, про який я не пам'ятаю ім'я:

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 ".docx" in file:
            print(os.path.join(r, file))

os.listdir (): отримати файли в поточному каталозі (Python 2)

У Python 2 ви, якщо ви хочете список файлів в поточному каталозі, ви повинні дати аргумент як "." або os.getcwd () в методі os.listdir.

>>> import os
>>> arr = os.listdir('.')
>>> arr
['$RECYCLE.BIN', 'work.txt', '3ebooks.txt', 'documents']

Підніматися в дереві каталогів

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

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

Отримати файли: os.listdir () у певному каталозі (Python 2 і 3)

>>> import os
>>> arr = os.listdir('F:\\python')
>>> 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]
>>> arr
['5bs_Turismo1.pdf', '5bs_Turismo1.pptx', 'esperienza.txt']

glob module - всі файли

import glob
print(glob.glob("*"))

out:['content', 'start.py']

наступний (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)

>output

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]

>>>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 - отримати лише файли у форматі txt

>>> import glob
>>> x = glob.glob("*.txt")
>>> x
['ale.txt', 'alunni2015.txt', 'assenze.text.txt', 'text2.txt', 'untitled.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

Інше використання glob

Якщо я хочу всі файли в каталозі:

>>> x = glob.glob("*")

Використання os.path.isfile, щоб уникнути каталогів у списку

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

> output

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

Використання pathlib з (Python 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

Якщо ви хочете використовувати осмислення списку

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

Отримайте всі і тільки файли за допомогою os.walk

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

>>> 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]
>>> x
['calculator.bat','calculator.py']

Отримайте лише каталоги з наступним і переходьте в каталог

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

Отримайте всі назви підрозділів гуляти

>>> 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 () від Python 3.5 на

>>> import os
>>> x = [f.name for f in os.scandir() if f.is_file()]
>>> 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
>>>

Ex. 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"))

> output

>'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("------------------------")
        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')


> Output

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

Ex. 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)

333
2018-01-03 15:36



Ви повинні додати аргумент шляху до listdir. - Alejandro Sazo
Цілком настійно рекомендується включити певний контекст / пояснення до коду, оскільки це робить відповідь корисною. - EJoshuaS
Я згоден, але я теж не помітив, що python2 вимагає аргументу, поки python3 є необов'язковим. Якщо ви покращте відповідь для обох версій python, це буде чудово :) - Alejandro Sazo
Добре, я пішов у Python 2 і знайшов відмінності, і я відредагував пост. - Giovanni Gianni
Немає причин робити це [f for f in os.listdir()]; os.listdir() вже повертає а list, так що це просто непотрібно копіювати оригінал list перед тим як відкинути його. - ShadowRanger


Одне-лінійне рішення отримати тільки список файлів (без підкаталогів):

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

або абсолютні шляхи управління:

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

144
2018-01-18 17:42



Тільки один вкладиш, якщо ти вже є import os. Здається менш лаконічним, ніж glob() для мене. - ArtOfWarfare
Проблема з glob полягає в тому, що папка під назвою something.something повертається glob ('/ home / adam /*.*') - Remi
У ОС X є щось називається зв'язком. Це каталог, який, як правило, слід трактувати як файл (наприклад, .tar). Чи хотіли б ви, щоб ті, котрі розглядались як файли чи каталоги? Використовуючи glob() буде розглядати його як файл. Ваш метод буде розглядати його як каталог. - ArtOfWarfare


Отримання шляхів повного файлу з каталогу та всіх її підкаталогу

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

Якщо ви хочете, ви можете відкрити та прочитати вміст або зосередитись лише на файлах з розширенням ".dat", як у наведеному нижче коді.

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

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


110
2017-10-11 00:55





З версії 3.4 є вбудовані ітератори для цього, що набагато ефективніше, ніж 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()]

Зауважте, що os.walk() використовує os.scandir() замість os.listdir() від версії 3.5, а його швидкість збільшилася в 2-20 разів відповідно PEP 471.

Дозвольте мені також рекомендувати читати коментарі ShadowRanger нижче.


57
2018-06-18 20:58



Дякую! Я думаю, що це єдине рішення, яке не повертає безпосередньо a list. Міг використати p.name замість першого p альтернативно, якщо воно є бажаним. - JeromeJ
Ласкаво просимо! Я б вважав за краще генерувати pathlib.Path() випадки, оскільки вони мають багато корисних методів, я б не хотів витрачати даремно. Ви також можете зателефонувати str(p) на них назви шляхів. - SzieberthAdam
Примітка os.scandir рішення буде більш ефективним, ніж os.listdir з os.path.is_file перевірте тощо, навіть якщо вам потрібен list (так що ви не користуєтесь леною ітерацією), тому що os.scandir використовує ОС, що надає API, які дають вам is_file інформація надається безкоштовно, оскільки вона повторюється, жодна передача в обидва кінці на диск на stat їх взагалі (на Windows, DirEntryщоб ви завершили stat інформація безкоштовно, на * NIX системах це потрібно stat за інформацією за межі is_file, is_dirі т. д., але DirEntry кеш на першому stat для зручності). - ShadowRanger
Я виявив, що це найбільш корисне рішення (використання pathlib) Я легко можу отримати конкретні типи розширень і абсолютні шляхи. Дякую! - HEADLESS_0NE
Ви також можете використовувати entry.name щоб отримати тільки ім'я файлу, або entry.path щоб отримати повний шлях. Немає більше os.path.join () по всьому місцю. - user136036