Python-从目录和子文件夹向列表中添加文件名(非完整路径)

Python-从目录和子文件夹向列表中添加文件名(非完整路径),python,python-os,Python,Python Os,这是针对Python2的 我有一段代码正在创建一个包含三个相同列表的对象dtry。每个列表都是所有文件,不包括带有文件夹的文件夹。这是可行的,但我想扩展它,使其也适用于子文件夹 我的工作代码如下: import os fldr = "C:\Users\jonsnow\OneDrive\Documents\my_python\Testing\Testing" dtry[:] = [] # clear list for i in range(3): dtry.append([t

这是针对Python2的

我有一段代码正在创建一个包含三个相同列表的对象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))])


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

这将成功创建三个列表,其中包含文件的名称,但不包含完整路径,并且仅包含fldr中的文件,而不包含文件夹

我希望它也能在fldr的子文件夹中搜索

不幸的是,我不知道如何让它这样做

我已经拼凑了另一段代码,列出了子文件夹中的所有文件,这很管用,但它列出了完整的路径,而不仅仅是文件名。详情如下:

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


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)

但这对我不起作用

有人能告诉我这里缺少什么吗


我再次尝试将dtry设置为三个列表,每个列表都是fldr中的所有文件以及其所有子文件夹中的文件。

以下是我能想到的最简单的方法,仅使用os.listdir即可获得所有文件名,而无需任何子路径:

这使用了我在评论中提到的递归思想

使用测试目录结构:

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

['a', 'c', 'i', 'h', 'f', 'e', 'b']
如果我更改此行:

result.append(entry)
致:

然后我得到:

['/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

除递归版本外,这些版本产生相同的结果。

您正在使一个简单的问题变得非常困难。这项工作:

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

你考虑过使用os.walk吗?这将为您提供一个包含dirpath、dirname和filename的元组。这将简化您的迭代,并帮助您专注于所需的部分。正如@askingaq所说,os.walk是一个不错的选择。这是一个经常使用递归解决的问题。你的函数只处理一个目录,但当它遇到子目录时会调用自己。我不理解1,2,3循环。在循环中不使用“i”。那该怎么办?你只想要三个相同的结果如果是这样,最好把所有的工作都做一次,然后把结果复制两次。是的,我只想要三个相同的结果。稍后,我将对每个子列表执行不同的操作。我很高兴接受你的建议,并在以后的阶段这样做。您提到使用os.walk,因为我在第二个代码块中生成完整文件路径的列表。我还应该在哪里使用os.walk?请您稍微明确一点,因为我这里缺少一些东西。请注意,glob是一个不需要安装的库,它是Python 2和Python 3的一部分。谢谢,我最终使用了os.walk方法。你能解释一下os.listdir方法是如何工作的吗?我想我能理解其中的大部分,但是'result=None'参数做什么呢?当然,没问题。使用递归方法,您将向每个递归级别传递一个结果列表。每个级别的文件都会不断添加到此列表中。您可以让最初的调用者传入一个空列表以启动流程。result=None所做的只是说明获取结果列表的参数是可选的。这使得调用者不必费心传递一个空列表。如果在该参数中未传递任何列表,则代码将创建初始空列表。当例程调用自身时,它总是传入一个列表参数。
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)]