我目前正处于一个项目中,我实际上是在尝试根据许多分散的xml文件创建一个树形结构,遗憾的是,这些文件并不是非常一致的。具体来说,我现在的观点是,给定一些具有给定文件扩展名的文件,我希望能够找到指示其布局的xml文档。幸运的是,文档总是具有相同的名称,但遗憾的是文档并不总是与我试图将其链接到的媒体文件位于相同的位置。我发现最明智的解决方法是在目录结构中查找具有相似名称的最近文件。但是,我在Python中设法做到这一点的唯一方法是通过使用os.walk来查找目录并查找文件。遗憾的是,这很慢,我希望能够为大量媒体文件做到这一点,所以我正在寻找更优雅的解决方案。下面是一些示例代码,显示了我目前的方法:
from os import listdir
from os.path import isfile, join, realpath
current_directory = "/path/to/example.mp3"
all_files = lambda path: [file for file in listdir(path) if isfile(join(path,file))]
filename = "test.xml"
found = False
while found is False:
current_directory = current_directory[:current_directory.rfind("/")]
current_files = all_files(current_directory)
if filename in current_files:
return current_files[current_files.index(filename)]
目录结构并不是很糟糕,以至于上面的方法将同时到达两个文件实例,但我仍然觉得上面的方法不是非常pythonic,并且比它真正需要的更复杂。有什么想法吗?
答案 0 :(得分:0)
os.walk
很聪明:当topdown
为True
时,您可以修改dirnames
以指定要检查的子目录。
使用它,可能使用某种状态机,会立即使您的代码更整洁 - 不需要listdir
,allfiles
或rfind
hackery。
<击> 撞击>
您的代码中没有递归树搜索,因此确实不需要os.walk()
。
如果我说得对,你的代码会检查当前dir的确切名称,然后一直向上检查FS。
path = os.path.dirname("/path/to/file.mp3")
target = "test.xml"
top = "/"
while True:
if os.path.isfile(os.path.join(path,target)):
#found
break
if path==top: #alternative check for root dir: if os.path.dirname(path)==path
#not found
break
path=os.path.dirname(path)
另一种方法是使用生成父母的生成器,但这对我来说似乎过于复杂。虽然这可能更像pythonic:
def walk_up(path,top):
while True:
yield path
if path==top: raise StopIteration
else: path=os.path.dirname(path)
found = None
for p in walk_up(os.path.dirname("/path/to/file.mp3"),"/"):
p = os.path.join(p,target)
if os.path.isfile(p):
found = p
break