I have a small problem. I am trying to move 20×500 images in 20 predefined folders. I can make this work with just 500 random images and I have identified the problem; I draw 500 random files, move them and then it tries doing it again but since it doesn’t update the random list, it fails when it reaches an image that it thinks is part of the random group but it has already been moved and thus fails. How do I “update” the random list of files so that it doesn’t fail because I move stuff? The code is:
import os import shutil import random folders = os.listdir(r'place_where_20_folders_are') files = os.listdir(r'place_where_images_are') string=r"string_to_add_to_make_full_path_of_each_file" folders=[string+s for s in folders] for folder in folders: for fileName in random.sample(files, min(len(files), 500)): path = os.path.join(r'place_where_images_are', fileName) shutil.move(path, folder)
Advertisement
Answer
I think the problem in your code is that the random.sample()
method leaves the original files
list unchanged. Because of this you have a chance of getting the same filename twice, but as you already moved it before you will have an error.
Instead of using sample
you could use this snippet:
files_to_move = [files.pop(random.randrange(0, len(files))) for _ in range(500)]
This will pop (thus removing) 500 random files from the files list and save them in files_to_move
. As you repeat this, the files
list becomes smaller.
This answer was inspired by this answer to the question Random Sample with remove from List.
This would be used like this:
import os import shutil import random folders = os.listdir(r'place_where_20_folders_are') files = os.listdir(r'place_where_images_are') string=r"string_to_add_to_make_full_path_of_each_file" folders=[string+s for s in folders] for folder in folders: files_to_move = [files.pop(random.randrange(0, len(files))) for _ in range(500)] for file_to_move in files_to_move: path = os.path.join(r'place_where_images_are', file_to_move) shutil.move(path, folder)