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()之后,您很少需要对列表进行整数索引访问。for在 Python 中,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 回答