我已经编写了代码,以找出两个给定文件夹(路径)之间的通用文件,以说明子文件夹的所有级别(如果存在)。
请建议是否有更有效的方法。如果指定了包含许多子文件夹级别的文件夹,则会花费太长时间。
def findCommonDeep(self,path1,path2):
commonfiles = []
for (dirpath1, dirname1, filenames1) in os.walk(path1):
for file in filenames1:
for (dirpath2, dirname2, filenames2) in os.walk(path2):
if (file in filenames2 and isfile(join(dirpath2, file))):
commonfiles.append(file)
print(commonfiles)
并使用路径调用此函数,如下所示:
findCommonDeep("/home/naseer/Python", "/home/naseer/C")
我知道,如果我存储任何给定路径的所有文件的列表,则可以降低执行速度。但我想那会耗尽内存。请指导我更有效地解决这个问题。
答案 0 :(得分:8)
您可以使用生成器表达式将os.walk
的输出转换为两个集合,并使用集合相交来有效地标识公共路径。
import os
def findCommonDeep(path1, path2):
files1 = set(os.path.relpath(os.path.join(root, file), path1) for root, _, files in os.walk(path1) for file in files)
files2 = set(os.path.relpath(os.path.join(root, file), path2) for root, _, files in os.walk(path2) for file in files)
return files1 & files2
要减少上面代码中的代码重复,您可以使用另一种列表理解:
import os
def findCommonDeep(path1, path2):
return set.intersection(*(set(os.path.relpath(os.path.join(root, file), path) for root, _, files in os.walk(path) for file in files) for path in (path1, path2)))
如果您只查找公用文件名而不是公用路径名,则可以使生成器表达式仅输出文件名:
def findCommonDeep(path1, path2):
return set.intersection(*(set(file for _, _, files in os.walk(path) for file in files) for path in (path1, path2)))
这效率更高,因为它利用了Python的集合交集操作,该操作的平均time complexity为O(min(len(n), len(m))
,而带有2个嵌套循环的代码始终需要O(n^2)
。