将字典列表写入CSV Python

时间:2015-11-27 10:13:09

标签: python csv dictionary

假设我有这样的词典数据集列表,

data_set = [
    {'Active rate': [0.98, 0.97, 0.96]},
    {'Operating Expense': [3.104, 3.102, 3.101]}
]

我需要迭代字典列表,并将键作为列标题及其值作为行,并将其写入CSV文件。

Active rate    Operating Expense
0.98           3.104
0.97           3.102
0.96           3.101

这就是我试过的

data_set = [
    {'Active rate': [0.98, 0.931588, 0.941192]},
    {'Operating Expense': [3.104, 2.352, 2.304]}
]

import csv

with open('names.csv', 'w') as csvfile:
    fieldnames = ['Active rate', 'Operating Expense']
    writer = csv.DictWriter(csvfile, fieldnames=fieldnames)

    writer.writeheader()
    writer.writerow({'Active rate': 0.98, 'Operating Expense': 3.102})
    writer.writerow({'Active rate': 0.97, 'Operating Expense': 3.11})
    writer.writerow({'Active rate': 0.96, 'Operating Expense': 3.109})

为简洁起见,我将键缩小为2,将值列表缩小为3.

如何解决这个问题?

由于

5 个答案:

答案 0 :(得分:3)

以下方法适用于您提供的数据结构:

import csv

data_set = [
    {'Active rate': [0.98, 0.97, 0.96]},
    {'Operating Expense': [3.104, 3.102, 3.101]}
]

fieldnames = ['Active rate', 'Operating Expense']
rows = []

for field in fieldnames:
    for data in data_set:
        try:
            rows.append(data[field])
            break
        except KeyError, e:
            pass

with open('names.csv', 'wb') as f_output:
    csv_output = csv.writer(f_output)
    csv_output.writerow(fieldnames)
    csv_output.writerows(zip(*rows))

为您提供以下CSV输出文件:

Active rate,Operating Expense
0.98,3.104
0.97,3.102
0.96,3.101

答案 1 :(得分:3)

d1 = {'Active rate': [0.98, 0.931588, 0.941192]}
d2 = {'Operating Expense': [3.104, 2.352, 2.304]}

with open('names.csv', 'w') as csvfile:
    fieldnames = zip(d1, d2)[0]
    writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
    writer.writeheader()

    for row in zip(d1['Active rate'], d2['Operating Expense']):
        writer.writerow(dict(zip(fieldnames, row)))

为了提高性能,您可能需要使用itertools.izip而不是zip,具体取决于列表的长度。

答案 2 :(得分:3)

(这个答案的缺点是使用外部库,但是)

pandas已经提供了非常强大而简单的工具来处理csv文件。您可以使用to_csv

请注意,您的数据结构结构不合理,因此我们首先将其转换为更直观的结构

data_set2 = { x.keys()[0] : x.values()[0] for x in data_set }

import pandas as pd
df = pd.DataFrame(data_set2)
df.to_csv('names.csv', index = False)

答案 3 :(得分:2)

data_set = [
    {'Active rate': [0.98, 0.97, 0.96]},
    {'Operating Expense': [3.104, 3.102, 3.101]}
]

首先,只是一个快速评论,您的初始数据结构并不一定有意义。你正在使用一个dicts列表,但每个dict似乎只使用一个键,这似乎打败了它的目的。

其他更有意义的数据结构将是这样的(使用每个dict结构,就像你现在拥有的那样,对于一个标签/值对,但至少dict用于告诉标签和值):

data_set = [
    {'label': 'Active rate', 'values': [0.98, 0.97, 0.96]},
    {'label': 'Operating Expense', 'values': [3.104, 3.102, 3.101]}
]

或者,更好的是,OrderedDict可以为您提供初始数据集的顺序和键/值映射的好处:

from collections import OrderedDict
data_set = OrderedDict()
data_set['Active rate'] = [0.98, 0.97, 0.96]
data_set['Operating Expense'] = [3.104, 3.102, 3.101]

当然,我们并不总是选择我们获得的数据结构,因此我们假设您无法对其进行更改。然后,您的问题就成了从初始数据集交换行和列角色的问题。实际上,您希望同时迭代多个列表,为此,zip非常有用。

import csv

fieldnames = []
val_lists = []
for d in data_set:
    # Find the only used key.
    # This is a bit awkward because of the initial data structure.
    k = d.keys()[0]
    fieldnames.append(k)
    val_lists.append(d[k])

with open('names.csv', 'w') as csvfile:
    writer = csv.writer(csvfile)    
    writer.writerow(fieldnames)

    for row in zip(*val_lists):
        # This picks one item from each list and builds a list.
        # The first row will be [0.98, 3.104]
        # The second row will be [0.97, 3.102]
        # ...
        writer.writerow(row)

请注意,当您使用DictWriter时,不需要zip,因为这意味着您需要重建字典而不会带来任何实际好处。

答案 4 :(得分:2)

此代码可以帮助您,而不必依赖于data_set

中的一定数量的词组
  

我已经添加了另一个关于'损失'键,测试

import csv

data_set = [
    {'Active rate': [0.98, 0.97, 0.96]},
    {'Operating Expense': [3.104, 3.102, 3.101]},
    {'Losses': [1.14, 2.28, 3.42]}
]

headers = [d.keys()[0] for d in data_set]

with open('names.csv', 'w') as csvfile:
    writer = csv.DictWriter(csvfile, fieldnames=headers)
    writer.writeheader()
    for item in zip(*[x.values()[0] for x in data_set]):
        more_results = list()
        more_results.append(headers)
        more_results.append(item)
        writer.writerow(dict(zip(*more_results)))

<强>输出:

enter image description here