使用列表理解用两个不同的代码写入文件

时间:2013-11-04 17:13:26

标签: python python-2.7 list-comprehension

我有两段代码,我认为是相同的;任何人都可以解释我在列表理解方面缺少的理由吗?

以下代码在写入文件时仅生成最后一个子文件夹的内容:

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]

所以,他们似乎与我完全相同,但他们显然不是。有人能指出我正确的方向吗?

3 个答案:

答案 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)