Создание / создание каталогов в Python (сложный) - PullRequest
4 голосов
/ 01 июля 2010

Я пытаюсь создать группу каталогов / подкаталогов, в которые я могу копировать файлы. Я работаю с Python, и я не могу найти хороший способ сделать это. У меня есть основной путь, от которого я уйду. Затем, после этого, у меня есть веса и No_Weights. Мужчина и Женщина следующие. В каждой из папок мужского и женского пола у меня есть этническая принадлежность (кавказская, афро-американская, азиатская, испанская, индо, другая, неизвестная). В каждой из этих папок у меня возраст от 20 до 70 лет (B20, 20, 30, 40, 50, 60, 70).

Я попытался сгенерировать все пути, поэтому все, что мне нужно было бы вызвать, это mkdir примерно 50 раз, но это примерно 150 строк кода (почти).

Есть ли простой способ создать все эти папки без необходимости делать это вручную?

Ответы [ 5 ]

18 голосов
/ 01 июля 2010
import itertools
import os

dirs = [["Weights", "No_Weights"],
        ["Male", "Female"],
        ["Caucasian", "African-American", "Asian", "Hispanic", "Indo", "Other", "Unknown"], 
        ["B20", "20", "30", "40", "50", "60", "70"]]

for item in itertools.product(*dirs):
    os.makedirs(os.path.join(*item))

itertools.product() создаст все возможные варианты пути, затем os.path.join() объединит подпути вместе, используя правильный синтаксис для вашей платформы.

РЕДАКТИРОВАТЬ: os.makedirs() необходимо вместо os.mkdir().Только первый создаст все промежуточные подкаталоги в полном пути.

3 голосов
/ 01 июля 2010

Этот пример поможет вам начать:

import itertools
import os.path

ROOT = r'C:\base\path'

sex = ('male', 'female')
ethnicity = ('Caucasian', 'African-American', 'Asian')
ages = ('B20', '20', '30')

for path in itertools.product(sex, ethnicity, ages):
    print os.path.join(ROOT, *path)

Модуль itertools - ваш друг: http://docs.python.org/library/itertools.html#itertools.product

2 голосов
/ 01 июля 2010

Просто сделайте что-то вроде этого:

main = 'somedir'
weight = ['weights', 'No_weights']
ethnicity = ['Caucasian', #the rest]
ages = ['B20'] +  range(20, 71, 10)

for w in weights:
    os.mkdir(os.path.join(main, w)
    for e in ethnicity:
        os.mkdir(os.path.join(main, w, e))
        for a in ages:
            os.mkdir(os.path.join(main, w, e, a))

и это должно позаботиться об этом ...

0 голосов
/ 01 июля 2010

os.makedirs может помочь - он превращает все промежуточные каталоги вплоть до «конечного», который вы указываете.

Другая проблема (генерирование всего «одного изстолбец A, один из столбца B, ... "комбинации) лучше всего рассматривать как проблему" подсчета в смешанных базах "- примерно, что-то вроде ...:

choices = [ ['Weights', 'Noweights'],
            ['Male', 'Female'],
            ['Caucasian', 'AfricanAmerican', ...
            ...
          ]
Ls = [len(x) for x in choices]
ct = [0] * len(Ls)

while True:
    p = [c[i] for i, c in zip(ct, choices)]
    os.makedirs(os.path.join(p))
    n = -1
    while n > -len(Ls):
      ct[n] += 1
      if ct[n] < Ls[n]: break
      ct[n] = 0
      n -= 1
    else:
      break

itertools.product это современный и лаконичный подход к генерации всех выборок «один из столбца А, и т. д.», и то, что я бы посоветовал в производственном программном обеспечении - просто:

for p in itertools.product(*choices):
    os.makedirs(os.path.join(p))

может заменить весь вышеприведенный код(!).Я думаю, что также стоит знать о подходе «подсчет в смешанных базах» на уровне более низкой абстракции, потому что он пригодится во многих случаях (включая случаи, когда кто-то застревает с использованием выпуска Python < 2.6; -).

0 голосов
/ 01 июля 2010

Есть несколько вложенных циклов for, а затем os.mkdir для каждого.Используйте os.path.join, чтобы объединить путь к каталогу.

Что-то вроде:

loop weights
    mkdir weight
    loop sexes
        mkdir weights + sex
        loop ethnicities
            mkdir weights + sex + ethnicity
            loop ages
                mkdir weights + sex + ethnicity + age

здесь цикл - это просто обычный цикл for:

for weight in ('weights', 'no_weights'):

mkdir - это os.mkdir

'+' - это os.path.join:

os.mkdir(os.path.join(weights, sex, ethnicity, age))

Редактировать: здесь может пригодиться dir_util, поэтому вам не нужно создавать каждый подкаталог

http://docs.python.org/release/2.5.2/dist/module-distutils.dirutil.html

loop weights
    loop sexes
        loop ethnicities
            loop ages
                mkpath weights + sex + ethnicity + age
...