-3

I am iterating through some folders to read all the objects in that list to later on move the not rejected ones. As the number of folders and files may vary, basically I managed to create a dictionary where each folder is a key and the items are the items. In a dummy situation I have: Iterating through the number of source of folders (known but may vary)

sourcefolder = (r"C:\User\Desktop\Test")
subfolders = 3 
for i in range(subfolders):
    Lst_All["allfiles" + str(i)] = os.listdir(sourcefolder[i])

This results in the dictionary below:

Lst_All = {
           allfiles0: ('A.1.txt', 'A.txt', 'rejected.txt')
           allfiles1: ('B.txt')
           allfiles2: ('C.txt')}

My issue is to remove the rejected files so I can do a shutil.move() with only valid files.

So far I got:

for k, v in lst_All.items():
    for i in v:
        if i == "rejected.txt":
            del lst_All[i]

but it returns an error KeyError: 'rejected.txt'. Any thoughts? Perhaps another way to create the list of items to be moved?

Thanks!

CDJB
  • 14,043
  • 5
  • 29
  • 55

2 Answers2

2

For a start, the members of your dictionary are tuples, not lists. Tuples are immutable, so we can't remove items as easily as we can with lists. To replicate the functionality I think you're after, we can do the following:

Lst_All = {'allfiles0': ('A.1.txt', 'A.txt', 'rejected.txt'),
          'allfiles1': ('B.txt',),
           'allfiles2': ('C.txt',)}

Lst_All = {k: tuple(x for x in v if x!="rejected.txt") for k, v in Lst_All.items()}

Which gives us:

>>> Lst_All
{'allfiles0': ('A.1.txt', 'A.txt'),
 'allfiles1': ('B.txt',),
 'allfiles2': ('C.txt',)}
CDJB
  • 14,043
  • 5
  • 29
  • 55
1

You should not iterate over a dictionary when removing element from that dictionary inside loop. Better to make an list of keys and then iterate over that. Also you do not need a separate loop to check whether rejected.txt is present in that directory.

keys = list(lst_All.keys())
for k in keys:
    if "rejected.txt" in lst_All[k]:
        del lst_All[k]

If you want to remove rejected.txt then you can only create another tuple without that element and insert in the dictionary with the key. You can do that like -

keys = list(lst_All.keys())
for k in keys:
    lst_All[k] = tuple((e for e in lst_All[k] if e != 'rejected.txt'))
kuro
  • 3,214
  • 3
  • 15
  • 31