2013-07-31 51 views
0

假设我们正在使用多个键值对从某个源读取数据。让我们用下面的列表为例:水平写入CSV

[{'key0': 'key0_value0', 'key1': 'key1_value0'}, 
{'key0': 'key0_value1', 'key1': 'key1_value1'}] 

从该列表读取第一个项目应导致CSV看起来像这样:

key_header | 0 
--------------------------- 
key0  | key0_value_0 
key1  | key1_value_0 

阅读的第二个项目现在应该导致以下:

key_header | 0   | 1 
---------------------------------------- 
key0  | key0_value_0 | key0_value_1 
key1  | key1_value_0 | key1_value_1 

这会一直进行到水平。算法写这是超出我的,我不知道是否​​将工作,因为它似乎假设数据将一次写入一行。

+0

使用发电机按顺序给他们,然后使用zip()。 –

回答

5

你必须首先收集所有的“列”,然后。你可以做到这一点的一切转换成一个列表的列表,然后使用zip(*columns)到列的列表转置到行的列表:

columns = [['key_header'] + sorted(inputlist[0].keys())] # first column 

for i, entry in enumerate(inputlist): 
    columns.append([i] + [entry[k] for k in columns[0][1:]]) 

with open(outputfilename, 'wb') as output: 
    writer = csv.writer(output) 
    writer.writerows(zip(*columns)) 

演示表示行输出:

>>> from pprint import pprint 
>>> inputlist = [{'key0': 'key0_value0', 'key1': 'key1_value0'}, 
... {'key0': 'key0_value1', 'key1': 'key1_value1'}] 
>>> columns = [['key_header'] + sorted(inputlist[0].keys())] # first column 
>>> for i, entry in enumerate(inputlist): 
...  columns.append([i] + [entry[k] for k in columns[0][1:]]) 
... 
>>> pprint(zip(*columns)) 
[('key_header', 0, 1), 
('key0', 'key0_value0', 'key0_value1'), 
('key1', 'key1_value0', 'key1_value1')] 
1

没有办法逐步写专栏,因为这不是如何文本文件(CSV文件的一个子集)的工作。您不能追加到文件中间的行/行;你所能做的就是在最后附加新行。

不过,我不知道为什么你总有需要做到这一点。只需在内存中转置列表,然后逐行写入。

例如:

values = [{'key0': 'key0_value0', 'key1': 'key1_value0'}, 
      {'key0': 'key0_value1', 'key1': 'key1_value1'}] 
transposed = zip(*(x.items() for x in values)) 
grouped = ([pairs[0][0]] + [pair[1] for pair in pairs] for pairs in transposed) 
writer.writerows(grouped) 

只需调换items是不是很够,因为你最终为每个值的key0副本,而不是仅仅一个副本。这就是grouped的用途。

+1

这是否假设'.items()'调用所有字典将以相同的顺序返回键?根据他们的插入历史是相同的也许有点脆弱? –