Python for 循环仅将最后一个列表作为值附加

Posted

技术标签:

【中文标题】Python for 循环仅将最后一个列表作为值附加【英文标题】:Python for loop appends only the last list as value 【发布时间】:2019-07-08 15:24:53 【问题描述】:

我正在遍历一个目录,并希望将文件夹中的所有文件存储为字典中的列表,其中每个键是一个文件夹,文件列表是值。

循环中的第一个打印准确地显示了我期望的输出。

但是第二个打印显示空值。

类初始化后的第三次打印显示最后一个子文件夹的列表作为每个键的值。

我忽略了什么或做错了什么?

class FileAndFolderHandling() :

    folders_and_files = dict()


    def __init__(self) :
        self.getSubfolderAndImageFileNames()


    def getSubfolderAndImageFileNames(self) :

        subfolder = ""
        files_in_subfolder = []

        for filename in glob.iglob('X:\\Some_Directory\\**\\*.tif', recursive=True) :

            if not subfolder == os.path.dirname(filename) and not subfolder == "" :
                print(subfolder + "  /  /  " + str(files_in_subfolder))
                self.folders_and_files[subfolder] = files_in_subfolder   
                files_in_subfolder.clear()
                print(self.folders_and_files)

            subfolder = os.path.dirname(filename) # new subfolder
            files_in_subfolder.append(os.path.basename(filename))



folder_content = FileAndFolderHandling()

print(folder_content.folders_and_files)

【问题讨论】:

【参考方案1】:

您遇到的问题似乎是您实际上总是使用相同的列表。

定义files_in_subfolder = [] 创建一个列表并在您刚刚定义的变量中分配一个指向该列表的指针。那么接下来发生的事情是,当您分配 self.folders_and_files[subfolder] = files_in_subfolder 时,您只是将指向列表的指针(在每次迭代中都相同)存储在字典中,而不是实际的列表中。

稍后,当您执行files_in_subfolder.clear() 时,您将清除该指针指向的列表,因此也清除字典的所有条目(因为它始终是同一个列表)。

为了解决这个问题,我建议您为字典中的每个不同条目创建一个 new 列表,而不是在每次迭代时清除它。也就是说,将files_in_subfolder 的定义从循环外移到循环内。

希望对你有帮助!

【讨论】:

谢谢。我将 files_in_subfolder 的声明更改为循环和 if - 有效。我知道这与引用分配有关。【参考方案2】:

你正在清除数组,从我看到的...

files_in_subfolder.clear()

删除它并确保在任何清除操作之前将您的值添加到folders_and_files 变量中。

【讨论】:

我只有在子文件夹更改后才被清除,其余的都是之前完成的。【参考方案3】:

听起来你在寻找defaultdict

我这样修改了你的代码:

import glob, os
from collections import defaultdict

class FileAndFolderHandling() :
    folders_and_files = defaultdict(list)

    def __init__(self) :
        self.getSubfolderAndImageFileNames()

    def getSubfolderAndImageFileNames(self) :
        for filename in glob.iglob(r'C:\Temp\T\**\*.txt', recursive=True) :
            # print(filename)
            subfolder = os.path.dirname(filename)
            self.folders_and_files[subfolder].append(os.path.basename(filename))


folder_content = FileAndFolderHandling()

print(dict(folder_content.folders_and_files))

Output:
'C:\\Temp\\T': ['X.txt'], 'C:\\Temp\\T\\X': ['X1.txt', 'X2.txt'], 'C:\\Temp\\T\\X2': ['X1.txt']

defaultdict(list) 为每个添加的新密钥创建一个新列表。这似乎是您希望在您的代码中发生的事情。

【讨论】:

谢谢。似乎使每个循环中的 clear() 和声明变得不必要 如果这对你有用,请考虑投票并接受这个答案。

以上是关于Python for 循环仅将最后一个列表作为值附加的主要内容,如果未能解决你的问题,请参考以下文章

Python“for in”循环打印列表中的最后一项

python:使用列表切片作为for循环的目标

从for循环Python打印数字列表作为数组

使用字典 get() 作为函数从地图创建 Python 列表与使用 for 循环创建字典 get() 列表

列表如何在 python 中使用 for 循环实际工作?

For循环中的Python最后一次迭代