简体   繁体   English

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

[英]Python for loop appends only the last list as value

I am looping through a directory and want to get all files in a folder stored as list in a dictionary, where each key is a folder and the list of files the value. 我正在遍历目录,并希望将文件夹中的所有文件作为列表存储在字典中,其中每个键是一个文件夹,文件列表是值。

The first print in the loop shows exactly the output I am expecting. 循环中的第一个输出准确显示了我期望的输出。

However the second print shows empty values. 但是,第二张显示为空值。

The third print after initialization of the class shows the list of the last subfolder as value for every key. 类初始化后的第三张打印显示最后一个子文件夹的列表,作为每个键的值。

What am I overlooking or doing wrong? 我忽略了什么或做错了什么?

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)

It seems like the problem you have is that you are actually using always the same list. 您似乎遇到的问题是您实际上总是使用相同的列表。

Defining files_in_subfolder = [] creates a list and assigns a pointer to that list in the variable you just defined. 定义files_in_subfolder = []会创建一个列表,并在您刚定义的变量中分配一个指向该列表的指针。 So what happens then is that when you assign self.folders_and_files[subfolder] = files_in_subfolder you are only storing the pointer to your list (which is the same in every iteration) in the dictionary and not the actual list. 因此,发生的事情是,当您分配self.folders_and_files[subfolder] = files_in_subfolder您仅将指向列表的指针(每次迭代都相同)存储在字典中,而不是实际列表中。

Later, when you do files_in_subfolder.clear() you are clearing the list to which that pointer was pointing to, and therefore to all the entries of the dictionary (as it was always the same list). 稍后,当您执行files_in_subfolder.clear()您将清除该指针指向的列表,并因此清除字典的所有条目(因为它始终是同一列表)。

To solve this, I would recommend you to create a new list for each different entry in your dictionary, instead of clearing it for each iteration. 为了解决这个问题,我建议您为字典中的每个不同条目创建一个列表,而不是为每次迭代清除它。 This is, move the definition of files_in_subfolder from outside the loop to inside of it. 这就是将files_in_subfolder的定义从循环外部移到循环内部。

Hope it helps! 希望能帮助到你!

You are clearing the array, from what I see... 从我所见,您正在清除阵列...

files_in_subfolder.clear()

Remove that and make sure your value gets added to the folders_and_files variable before any clear operation. 删除该行,并确保在执行任何清除操作之前将您的值添加到folder_and_files变量中。

It sounds like you are after defaultdict . 听起来您好像在defaultdict之后。

I adapted your code like this: 我像这样修改了您的代码:

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']}

The defaultdict(list) makes a new list for every new key added. defaultdict(list)为添加的每个新密钥创建一个新列表。 This is what you seems to want to happen in your code. 这就是您似乎想要在代码中发生的事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM