0

各サブフォルダーに100個のファイル(または最後のフォルダーの残りのファイル)が含まれるように、サブフォルダー(dump_1、dump_2、...)に移動(作成する)したい多くのファイルを含むフォルダーがあります。テストのために、次のような小さなテキスト ファイルを作成しました。

rootdir='d:/t2/'
for i in range(1000):
    f=open(rootdir+"file_"+str(i)+".txt","w")
    f.write("This is file "+str(i))
    f.close()

サブフォルダーを作成してファイルを移動するためのコードは次のとおりです。

import random
files=os.listdir(rootdir)
random.shuffle(files)
count=1
while files:
    newdir=(rootdir+"dump_"+str(count).zfill(2)+"/")
    os.mkdir(newdir)
    for a,b in enumerate(files):
            os.rename(rootdir+b,newdir+b)
            files.remove(b)
            if a==99:
                break
    count+=1

結果は非常に奇妙です。最初の 9 つのフォルダーには、必要に応じて 100 個のファイルが含まれています。ただし、次のサブフォルダーには、50、25、13、6、3、2、および 1 個のファイルが含まれています。それがなぜなのか、どうすれば修正できるのか、誰にも手がかりがありますか? ありがとうございました!

4

4 に答える 4

1

ファイルを繰り返し処理し、必要に応じて新しいディレクトリを作成する方がよいのではないでしょうか:

import random
files = os.listdir(rootdir)
random.shuffle(files)
count = 1
newdir = None
for filename in files:
    if count % 100 == 1 or newdir is None:
        newdir = rootdir + "dump_" + str(count).zfill(2) + "/"
        os.mkdir(newdir)
    os.rename(rootdir + filename, newdir + filename)
    count += 1

サイクルを節約し、ロジックを明確にします。また、オリジナルから、バッチが 99 ファイルか 100 ファイルかがわかりませんでした。ただし、100 を 99 に変更するのは簡単です。また、リストからファイルを削除する必要はありません。

于 2012-08-04T19:29:17.353 に答える
1

おそらく、その上に列挙されたループ内の変数「ファイル」を変更することに関連しています。例えば:

>>> l = [1,2,3,4,5,6,7,8,9]
>>> for a, b in enumerate(l):
...     l.remove(b)    
...     print a
... 
0
1
2
3
4

次のように、列挙でファイルリストのコピー(またはスプライス)を作成できます

for a, b in enumerate(files[:100]):
于 2012-08-04T16:43:52.597 に答える
0

すべての助けをどうもありがとう!以下のコードですべてを組み合わせてみましたが、魅力のように動作します!

rootdir='d:/t2/'
import random
files = os.listdir(rootdir)
random.shuffle(files)
newdir = None
for n,filename in enumerate(files):
    if n%100 == 0 or newdir is None:
        newdir = rootdir + "dump_" + str(divmod(n,100)[0]).zfill(2) +"/"
        os.mkdir(newdir)
    os.rename(rootdir + filename, newdir + filename)
于 2012-08-05T19:22:23.487 に答える
0

enumerateリストの要素を繰り返します。ジェネレーターとして、要求されたときに各反復を実行します。ループ内で、リストを繰り返し処理しているため、リストからアイテムを削除しています。

そうすれば、現在の要素を削除すると、ジェネレーターは次の反復を生成する前に、既に次の要素を指しています。その結果、2 番目のエントリごとにスキップされます。

>>> myList = [i for i in range(10)]
>>> for i, j in enumerate(myList):
        print(i, j)
        myList.remove(j)

0 0
1 2
2 4
3 6
4 8

今できることは、列挙自体が削除の影響を受けないように、反復のコピーを作成することです。もう 1 つの方法は、実際にリストから要素を削除する必要がないように、ループ全体を改善することです。

于 2012-08-04T16:49:17.337 に答える