Python Forum

Full Version: Is it possible to avoid 2 loops inside another loop?
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Assume I have the following folders inside a folder called Repository.
  • Space
  • Landscape\Bridges

I want to go though each folder under the Repository and before I work with the folders, I need to make sure they meet certain specifications:
  • It is in fact a folder
  • The folder isn't empty
  • The folder doesn't contain a sub folder.

Under the following specifications the Landscape\Bridges folder would not be processed, it will be ignored.

Here is my code that does this:

def rename_images(self):

     for folder in self._root_source.iterdir():

         if self._folder_is_valid(folder=folder): 
             _rename_and_move_images(folder=path, destination=destination, start=start)


 def _folder_is_valid(self, folder) -> bool:

    return (folder.is_dir() 
            and self._get_number_of_items_in(folder=folder)
            and not self._if_subdirectories_contain_directories(folder=folder))


 def _if_subdirectories_contain_directories(self, folder : Path) -> int:
     folder_lst = [sub_folder for sub_folder in folder.iterdir() if sub_folder.is_dir()]


 def _rename_and_move_images(self, folder: Path, destination: Path, start: int):

     for number, image in enumerate(folder.iterdir(), start=start):
        # Loop, rename and move the file.
I have a for loop, and inside I have an if statement that calls self._if_subdirectories_contain_directories(folder=folder) which uses a for loop to determine if any subfolders exist. This means a for loop inside another for loop.

When that validation is done, I call def _rename_and_move_images(self, folder: Path, destination: Path, start: int). Which uses a for loop to rename and move the images inside the valid folder.

Simply put, I have a for loop that starts another for loop, and when that's done, I start another one.

I'm aware that nested for loops are bad practice, so is it possible to clean this up so that I don't use nested for loops?
(Nov-26-2019, 06:03 PM)SvetlanaofVodianova Wrote: [ -> ]I'm aware that nested for loops are bad practice

I'm not aware of this. Nested loops are a common tool in programming. They're only a problem if one of the loops is a problem, and loops can be a problem without nesting them. I don't see any problems with the loops you have in your code.
You could simplify things with os.walk()
import os

def _rename_images(self):
    for folder in self._valid_folders():
        self._rename_and_move_images(...)

def _valid_folders(self):
    for folder in self._subfolders(self._root_source):
        dirnames, filenames = next(os.walk(folder))[1:]
        if filenames and not dirnames: # folder not empty and without subfolder
            yield folder

def _subfolders(self, folder):
    for dirname in next(os.walk(folder))[1]:
        yield folder / dirname