Python-从目录和子文件夹向列表中添加文件名(非完整路径)
这是针对Python2的 我有一段代码正在创建一个包含三个相同列表的对象dtry。每个列表都是所有文件,不包括带有文件夹的文件夹。这是可行的,但我想扩展它,使其也适用于子文件夹 我的工作代码如下: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
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)]