3

我有两段我认为是等价的代码;谁能解释我在列表理解方面缺少的理由?

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

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]

所以,它们看起来和我一模一样,但显然不是。有人可以指出我正确的方向吗?

4

3 回答 3

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)

现在,除了该列表理解的最后一个结果之外,您并没有丢弃所有结果。

于 2013-11-04T17:15:56.017 回答
1

在第一个代码filenames中,每次您一直分配给它时都会重置。在循环之后,它只包含循环最后一次迭代的值。

在第二个代码中,您最终会得到由os.walk(directory).

于 2013-11-04T17:15:43.177 回答
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)
于 2013-11-04T17:16:21.723 回答