4

ファイルをコピーできる一連のディレクトリ/サブディレクトリを作成しようとしています。私はPythonで作業していますが、これを行う良い方法を見つけることができないようです. 分岐する主要なパスがあります。その後、Weights と No_Weights があります。男性と女性のフォロー。男性と女性の各フォルダー内には、それぞれの民族 (白人、アフリカ系アメリカ人、アジア人、ヒスパニック系、インド系、その他、不明) があります。これらの各フォルダー内には、20 歳未満から 70 歳以上 (B20、20、30、40、50、60、70) までの年齢範囲があります。

すべてのパスを生成しようとしたので、mkdir を約 50 回呼び出すだけで済みますが、それは約 150 行のコードです (ほとんど)。

これらすべてのフォルダを手動で作成する必要なく簡単に作成する方法はありますか?

4

5 に答える 5

18
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()。前者のみが、すべての中間サブディレクトリをフルパスで構築します。

于 2010-07-01T15:00:38.327 に答える
3

この例で始めることができます。

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

于 2010-07-01T15:02:04.563 に答える
2

次のようなことをしてください。

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))

そしてそれはあなたのためにそれの世話をする必要があります...

于 2010-07-01T15:02:20.330 に答える
0

os.makedirsが役立ちます。指定した「リーフ」ディレクトリまで、すべての中間ディレクトリを作成します。

もう 1 つの問題 (「列 A から 1 つ、列 B から 1 つ、...」の組み合わせをすべて生成する) は、「混合基数でカウントする」問題としてアプローチするのが最適です。

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すべての「列Aなどから1つ」のピックを生成するための最新かつ簡潔なアプローチであり、本番ソフトウェアでアドバイスすることは次のとおりです。

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

上記のコードをすべて置き換えることができます (!)。< 2.6多くの場合 (Python リリースの使用に行き詰まった場合を含む;-)に役立つため、「混合ベースでカウントする」低抽象化レベルのアプローチを認識することも価値があると思います。

于 2010-07-01T15:06:12.497 に答える
0

ネストされた 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
于 2010-07-01T14:55:42.533 に答える