我有两段代码,我认为是相同的;任何人都可以解释我在列表理解方面缺少的理由吗?
以下代码在写入文件时仅生成最后一个子文件夹的内容:
for root, directories, files in os.walk(directory):
filenames = [os.path.join(root, filename) for filename in files]
然而,下面的代码完全符合我的要求(写入根目录及其子目录的所有内容):
allfiles = [os.path.join(root,f) for root,dirs,files in os.walk(directory) for f in files]
所以,他们似乎与我完全相同,但他们显然不是。有人能指出我正确的方向吗?
答案 0 :(得分:3)
首先,您不使用列表推导写入文件。您正在使用列表推导来构建完整文件路径的列表。
第一个列表理解应用于os.walk()
方法找到的每个目录。根据主directory
路径下方的目录数量,可以多次调用它。
第二个列表理解适用于所有目录和文件。它只会被调用一次,并构建整个directory
文件系统结构中所有文件的列表。
如果您希望第一个给出相同的结果,则需要扩展列表对象:
all_files = []
for root, directories, files in os.walk(directory):
filenames = [os.path.join(root, filename) for filename in files]
all_files.extend(filenames)
现在你不会丢弃除列表理解的最后结果之外的所有结果。
答案 1 :(得分:1)
在第一个代码filenames
每次重置时都会重置。在循环之后,它只包含循环中最后一次迭代的值。
在第二个代码中,您最终会得到os.walk(directory)
生成的所有值的结果。
答案 2 :(得分:1)
在你的第一个循环中:
for root, directories, files in os.walk(directory):
filenames = [os.path.join(root, filename) for filename in files]
您正在循环的每次迭代中将filenames
重新分配给新的列表解析。这导致filenames
仅是os.walk()
中最后一个目录的列表理解。
您想将其更改为:
filenames = []
for root, directories, files in os.walk(directory):
filenames.extend(os.path.join(root, filename) for filename in files)