Стараясь избегать вложенных циклов - PullRequest
1 голос
/ 05 февраля 2020

Как мне избавиться от этих вложенных циклов for в моем коде? Я пытался использовать понимание списка, но не смог создать ничего хорошего. Спасибо за помощь! Вот часть моего кода:

    folders = [i for i in range(1, int(number_of_folders) + 1)]
    subfolders = [i for i in range(1, int(number_of_subfolders) + 1)]
    files = [i for i in range(1, int(number_of_files) + 1)]        

    for i in folders:
        folderpath = path + "/folder-" + str(i)

        for j in subfolders:
            subfolderpath = folderpath + "/subfolder-" + str(j)
            os.makedirs(subfolderpath)

            for k in files:
                file_path = subfolderpath + "/files-" + str(j) + '-' + str(k) + ".txt"
                open(file_path, "w")

Ответы [ 3 ]

1 голос
/ 05 февраля 2020

В следующем коде используйте список пониманий для формирования всех подпапок и имен файлов и:

all_subfolders_list = [f"{path}/folder-{str(i)}/subfolder-{str(j)}/"
                  for i in range(1, int(number_of_folders) + 1)
                  for j in range(1, int(number_of_subfolders) + 1)]

all_filenames = [f"{subfolder_path}{k}" for subfolder_path in all_subfolders_list
                 for k in range(1, int(number_of_files) + 1)]

for subfolderpath in all_subfolders_list:
    os.makedirs(subfolderpath)

for file_path in all_filenames:
    open(file_path, "w")
1 голос
/ 05 февраля 2020

Я не уверен, почему вы захотите изменить свой код для использования списочных представлений, поскольку он достаточно ясен и эффективен. Но прямолинейное преобразование вашего кода в списочные выражения будет:

import os

number_of_folders = 2
number_of_subfolders = 3
number_of_files = 4

path = 'path'

def create_dir_and_file(file_path, file_name):
      os.makdedirs(file_path, exist_ok=True)
      open(file_name, "w")

[create_dir_and_file(f'{path}/folder-{i}/subfolder{j}', f'files{j}-{k}.txt')
      for i in range(1, int(number_of_folders) + 1)
      for j in range(1, int(number_of_subfolders) + 1)
      for k in range(1, int(number_of_files) + 1)]
1 голос
/ 05 февраля 2020

Сначала вы можете сократить код в каждом l oop и привести в порядок с помощью os.path.join:

for i in folders:
        for j in subfolders:
            subfolder_path = os.path.join(path, f"folder{i}", f"subfolder{j}")
            os.makedirs(subfolder_path)
            for k in files:
                file_path = os.path.join(subfolderpath, "files-{j}-{k}.txt")
                open(file_path, "w")

И затем первые 2 цикла можно превратить в 1 с помощью itertools.product:

import itertools

for i,j in itertools.product(folders, subfolders):
    subfolder_path = os.path.join(path, f"folder{i}", f"subfolder{j}")
    os.makedirs(subfolder_path)
    for k in files:
         file_path = os.path.join(subfolderpath, "files-{j}-{k}.txt")
         open(file_path, "w")

Но как насчет создания функции для создания пути к файлу, если он не существует? Тогда мы можем сгущаться до одного для l oop.

def open_and_create(folder_path, file_name, *a):
    os.makedirs(folder_path, exist_ok=True)
    return open(os.path.join(folder_path, file_name) *a)

for i,j,k in itertools.product(folders, subfolders, files):
    subfolder_path = os.path.join(path, f"folder{i}", f"subfolder{j}")
    open_and_create(subfolder_path, "files-{j}-{k}.txt", 'w')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...