Python - добавление имен файлов (не полных путей) в список из каталога и подпапок - PullRequest
0 голосов
/ 03 апреля 2019

Это для Python 2.

У меня есть кусок кода, который создает объект (dtry), содержащий три идентичных списка.Каждый список - это все файлы (кроме папок) с папкой.Это работает, но я хочу расширить его для работы с подпапками.

Мой рабочий код выглядит следующим образом:

import os

fldr = "C:\Users\jonsnow\OneDrive\Documents\my_python\Testing\Testing"
dtry[:] = []  # clear list

for i in range(3):
        dtry.append([tup for tup in os.listdir(fldr)
                     if os.path.isfile(os.path.join(fldr, tup))])

Это успешно создает три списка, содержащие имена, но не полные путифайлов (и только файлы, а не папки) внутри fldr.

Я хочу, чтобы это также осуществляло поиск во вложенных папках fldr.

К сожалению, я не могу понять, как заставить это делатьитак.

Я собрал еще один фрагмент кода, который также перечисляет все файлы во вложенных папках (и так далее), но в нем перечислены полные пути, а не только имена файлов.Это выглядит следующим образом:


import os

fldr = "C:\Users\jonsnow\OneDrive\Documents\my_python\Testing\Testing"
dtry[:] = []  # clear list

for i in range(3):
        dtry.append([os.path.join(root, name)
                     for root, dirs, files in os.walk(fldr)
                     for name in files
                     if os.path.isfile(os.path.join(root, name))])

Я попытался изменить строку:

dtry.append([os.path.join(root, name)

на

tup for tup in os.listdir(fldr)

, но это не работает для меня.

Может кто-нибудь сказать мне, что мне здесь не хватает?

Опять же, я пытаюсь сделать dtry тремя списками, каждый из которых представляет собой все файлы в fldr и файлы во всех его всех.его подпапок.

Ответы [ 2 ]

0 голосов
/ 03 апреля 2019

Вы делаете легкую проблему очень сложно.Это работает:

from glob import glob

files = glob(r'C:\Users\jonsnow\OneDrive\Documents\my_python\Testing\Testing\**\*', recursive=True')
result = [files for _ in range(3)]

Обратите внимание, что это создает список с тремя ссылками на исходный список.Если вам нужны три идентичные копии:

from glob import glob

files = glob(r'C:\Users\jonsnow\OneDrive\Documents\my_python\Testing\Testing\**\*', recursive=True)
result = [files.copy() for _ in range(3)]
0 голосов
/ 03 апреля 2019

Вот самый простой способ, которым я могу придумать, чтобы получить все имена файлов без каких-либо подпутей, используя просто os.listdir () :

import os
from pprint import pprint

def getAllFiles(dir, result = None):
    if result is None:
        result = []
    for entry in os.listdir(dir):
        entrypath = os.path.join(dir, entry)
        if os.path.isdir(entrypath):
            getAllFiles(entrypath ,result)
        else:
            result.append(entry)
    return result

def main():
    result = getAllFiles("/tmp/foo")
    pprint(result)

main()

Это использует идею рекурсии Iупоминается в моем комментарии.

С тестовой структурой каталогов:

/tmp/foo
├── D
│   ├── G
│   │   ├── h
│   │   └── i
│   ├── e
│   └── f
├── a
├── b
└── c

Я получаю:

['a', 'c', 'i', 'h', 'f', 'e', 'b']

Если я изменю эту строку:

result.append(entry)

до:

result.append(entrypath)

тогда я получаю:

['/tmp/foo/a',
 '/tmp/foo/c',
 '/tmp/foo/D/G/i',
 '/tmp/foo/D/G/h',
 '/tmp/foo/D/f',
 '/tmp/foo/D/e',
 '/tmp/foo/b']

Чтобы получить точный результат, который вы хотели, вы можете сделать

dtry = [getAllFiles("/tmp/foo")]
dtry.append(list(dtry[0]))
dtry.append(list(dtry[0]))

И если вы хотитеиспользовать os.walk , который является более компактным, вот два варианта этого:

def getAllFiles2(dir):
    result = []
    for root, dirs, files in os.walk(dir):
        result.extend(files)
    return result

def getAllFilePaths2(dir):
    result = []
    for root, dirs, files in os.walk(dir):
        result.extend([os.path.join(root, f) for f in files])
    return result

Они дают те же результаты (в порядке порядка), что и рекурсивные версии.

...