将字典列表写入 CSV Python

Posted

技术标签:

【中文标题】将字典列表写入 CSV Python【英文标题】:Write list of dictionary into CSV Python 【发布时间】:2016-03-01 12:28:31 【问题描述】:

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

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。

如何解决这个问题?

谢谢

【问题讨论】:

真正的问题是什么? 您想知道如何以某种方式自动写入每一行而不是手动将值放在一起吗? 是的。我需要知道如何自动编写每一行。 【参考方案1】:
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,具体取决于列表的长度。

【讨论】:

itertools.izip 对于更大的数据集确实是一个很好的建议。 (由于索引的原因,替换zip(d1, d2)[0] 可能会导致问题,但这应该不难解决。【参考方案2】:

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

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

【讨论】:

【参考方案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)

【讨论】:

一定有人投了反对票,你只能希望他们回来检查。【参考方案4】:
data_set = [
    'Active rate': [0.98, 0.97, 0.96],
    'Operating Expense': [3.104, 3.102, 3.101]
]

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

其他更有意义的数据结构是这样的(每个 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)

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

【讨论】:

您还可以按照@MartinEvans 的建议使用writerows(zip(*val_lists)) 更简洁地完成最后一部分。【参考方案5】:

此代码将帮助您,而无需绑定到 data_set 中的特定数量的字典

我添加了另一个带有“Losses”键的字典来测试

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)))

输出:

【讨论】:

"此代码将帮助您,而不会被绑定到 data_set 中的特定数量的字典":我认为大多数其他答案已经考虑到了这一点。 @Bruno 我不会根据其他答案编写代码。无论如何感谢您的建议。 你能让它兼容 Python 3 吗? @AndrésPérez-AlbelaH,对不起,我当然没有暗示抄袭,只是说这一点(data_set 中的其他字典)已经在其他答案中得到处理。您的答案与其他答案的主要区别在于它仍然使用DictWriter。我不确定重建 dict 和使用 DictWriter 是否值得,这似乎更有效。 @Bruno 也许你可以帮我修改我的答案,而不是鼓励他不要选择我的答案。

以上是关于将字典列表写入 CSV Python的主要内容,如果未能解决你的问题,请参考以下文章

如何将带有嵌套字典的列表写入 csv 文件?

Python将csv写入字典列表,其中标题作为键,行作为值

将 Python 列表和字典中的数据写入 CSV

将python字典写入CSV列:第一列的键,第二列的值

从列表的字典中提取列表,然后附加到数据框

Python:将嵌套字典写入 CSV