2012-05-13 18 views
9

同じ構造を持つ複数のzipファイルがあります。これらのファイルには、ルートレベルのXMLファイルが含まれています。各zipファイル内のすべてのファイルは一意です(zipファイル全体で重複しません)。私は、すべてのzipファイルのすべてのXMLファイルを(元のzipファイルと同じ構造の)単一のzipファイルに結合する必要があります。これを行うにはどのように最善を尽くすための提案?ありがとう。複数のzipファイルをPythonの単一のzipファイルにマージする

+3

これらをすべて解凍して新しいものを作成しますか? – sarnold

+3

これは最も明白なアプローチです。最終的なzipファイルとして1つを選択し、他のファイルからファイルを抽出して最終的なファイルに追加することもできますが、もっと速くなるかどうかはわかりません。 – jgritty

+0

@sarnoldありがとうございます。私もこの考え方を考えていましたが、それをよりエレガントにする方法があるかどうかは分かりませんでした。 –

答えて

11

これは、私が思い付くことができ、最短バージョンである:私にはこれがベストです、選択肢をテストすることなく

>>> import zipfile as z 
>>> z1 = z.ZipFile('z1.zip', 'a') 
>>> z2 = z.ZipFile('z2.zip', 'r') 
>>> z1.namelist() 
['a.xml', 'b.xml'] 
>>> z2.namelist() 
['c.xml', 'd.xml'] 
>>> [z1.writestr(t[0], t[1].read()) for t in ((n, z2.open(n)) for n in z2.namelist())] 
[None, None] 
>>> z1.namelist() 
['a.xml', 'b.xml', 'c.xml', 'd.xml'] 
>>> z1.close() 

ソリューションので、 - 両方のzipファイルを仮定すると、含まれています(あまりにも、おそらく最も明白な!)同じ量のデータでは、この方法では半分(1ファイル)の圧縮解除と再圧縮が必要です。

PS:リストの理解は、コンソールの1行に指示を保存するだけです(デバッグのスピードを上げます)。良いpythonicコードは、結果のリストは目的を果たさないので、適切なforループを必要とするでしょう...

HTH!

+0

ありがとう、私はさまざまな数のzipファイルを持っていますが、私はもっと一般的なアプローチが必要です。 –

+1

@DaveCrumbacher:私が誤解していない限り、複数のファイルをマージするためにこの手法を使用するには、ループを追加するだけです: 'for zfile in(z2、z3、z4、...)' ...私は何かを逃していますか? – mac

+0

はい、@mac、あなたは正しいです。ありがとう。 –

6

ここで私が思いついたのは、@macのおかげです。これが現在実装されている方法では、最初のzipファイルは、他のzipファイルのすべてのファイルを含むように変更されています。

import zipfile as z 

zips = ['z1.zip', 'z2.zip', 'z3.zip'] 

""" 
Open the first zip file as append and then read all 
subsequent zip files and append to the first one 
""" 
with z.ZipFile(zips[0], 'a') as z1: 
    for fname in zips[1:]: 
     zf = z.ZipFile(fname, 'r') 
     for n in zf.namelist(): 
      z1.writestr(n, zf.open(n).read()) 
+5

'zipfile.ZipFile()'はコンテキストマネージャでもあるので、 'z1.close()'を 'z.ZipFile(zips [0]、 'a')でz1:後続のコード。読み込みオブジェクトと同じです。 – glglgl

+2

ありがとう@glglgl。私はこのアプローチを反映するために私の答えを更新しました。 –

関連する問題