0

多かれ少なかれこのように見える入力csvファイルの数が不明です(幅をさまざまな長さに設定します)

Header1, Header2, Header3, Header4
1,2,3,4
11,22,33,44
1,2,3,4

出力は次のようになります。

Header1,Header3, ,Header1,Header3, ,...
1,3, ,1,3, ,... 
...

現在、すべての入力ファイルを文字列に読み取ることができ、各ファイルの最初の行を読み取って目的の形式で出力する方法を知っていますが、ループを作成して各ファイルの次の行に移動する方法に行き詰まり、そのデータを印刷します。ファイルが終了したときの長さが異なるため、それを処理する方法がわかりません。形式を維持するためのプレースホルダーとして空白を入れます。以下は私のコードです。

csvs = []
hold = []
i=0         # was i=-1 to start, improved
for files in names:
    i=i+1
    csvs.append([i])
    hold.append([i])

#z=0
for z in range(i):
    # putting csv files into strings
    csvs[z] = csv.reader(open(names[z],'rb'), delimiter=',')

line = []    
#z=0
for z in range(i):
    hold[z]=csvs[z].next()
    line = line + [hold[z][0], hold[z][3], ' ']

print line
writefile.writerow(line)

names は、csv ファイルのパスを保持する文字列です。また、私はこれにかなり慣れていないので、私が物事をより良くできる場所を見つけたら、私はすべて耳にします.

4

2 に答える 2

3

一部のファイルが他のファイルよりも長い場合に行をマージする方法を知っていると仮定しましょう。行とファイルの繰り返しを簡単にする方法を次に示します。

from itertools import izip_longest 
# http://docs.python.org/library/itertools.html#itertools.izip_longest

# get a list of open readers using a list comprehension
readers = [csv.reader(open(fname, "r")) for fname in list_of_filenames]

# open writer
output_csv = csv.writer(...)

for bunch_of_lines in izip_longest(*readers, fillvalue=['', '', '', '']):
  # Here bunch_of_lines is a tuple of lines read from each reader,
  # e.g. all first lines, all second lines, etc
  # When one file is past EOF but others aren't, you get fillvalue for its line.
  merged_row = []
  for line in bunch_of_lines:
      # if it's a real line, you have 4 items of data.
      # if the file is past EOF, the line is fillvalue from above
      #   which again is guaranteed to have 4 items of data, all empty strings.
      merged_row.extend([line[1], line[3]]) # put columns 1 and 3
  output_csv.writerow(merged_row)

このコードは、最も長いファイルが終了した後にのみ停止し、ループはわずか 5 行のコードです。ヘッダーは自分で考えられると思います。

注: Python では、ループとリスト内包表記range()がどのように機能するかを理解した後で、リストへの整数インデックス アクセスが必要になることはほとんどありません。forPython では、forforeachの言語と同じです。インデックスとは関係ありません。

于 2012-05-04T16:53:13.447 に答える
1

これにより、出力に表示された予備のコンマは得られませんが、追加するたびに余分な空白フィールドをデータにポップするだけで追加するのは難しくありません。

import csv

names=['test1.csv','test2.csv']
csvs = []
done = []
for name in names:
    csvs.append(csv.reader(open(name, 'rb')))
    done.append(False)

while not all(done):
    data = []
    for i, c in enumerate(csvs):
        if not done[i]:
            try:
                row = c.next()
            except StopIteration:
                done[i] = True
        if done[i]:
            data.append('')
            data.append('')
            # data.append('')  <-- here
        else:
            data.append(row[0])
            data.append(row[3])
            # data.append('')   <-- and here for extra commas
    if not all(done):
        print ','.join(data)

また、これが長時間実行されるプロセスの一部である場合は、明示的に閉じる必要はありません。

于 2012-05-04T16:46:51.880 に答える