使用Dictwriter的CSV中的动态标头

时间:2017-10-04 08:23:49

标签: python csv

我现有的代码使用csv.DictWriter将字典列表写入CSV。但今天出现了一个新案例,即第三方API响应中的字典键是不同的,即某些响应带有字典中的附加键,或者某些时候响应字典中缺少某些键。

我们想要一个包含所有标题的CSV作为字典键并关联CSV,这些标题的所有关键值应该是相应的字典值

UPDATE 我正在寻找一种解决方案,我不需要将所有结果存储在内存中。我正在获取大约1300个API调用,这些调用在AWS lambda上使用128MB。如果我将它存储在一个列表中(1300个调用*每批25个项目= 32500个字典),肯定会使用超过512MB的Lambda内存。

例如。样本响应数据(response.get('data', [])的结果):

 [{"a": 1, "b": 2, "d": 3}, {"b": 5, "c": 3, "d":3}, {"a": 22, "b": "25", 8, 9} ... etc]  

在这种情况下,我的CSV应为:

a      b      c      d
1      2             3
5             3      3
22     25     8      9

例如。

# Fetch Third party API data in batches 25 records/batch
def fetch_api_data(self, url, payload):
    while True:
        response = requests.post(url, json=payload).json()
        yield response.get('data', [])
        if 'next_page_url' not in response:
              break
        url = response['next_page_url']


def update_recs_to_csv(self, url, payload):
    responses = fetch_api_data(url, payload)
    first_25_rows = next(responses)
    first_row = first_25_rows[0]
    keys = first_row.keys() 
    with open("output.csv", "w") as output_file:
         dict_writer = csv.DictWriter(output_file, keys)
         dict_writer.writeheader()
         dict_writer.writerow(first_row)
         for row_dict in responses:
             dict_writer.writerow(row_dict)   #-- This row_dict comes with different (varying) keys

1 个答案:

答案 0 :(得分:2)

在一个简单的例子中,我们说你的回答是:

response = [{"a": 1, "b": 2, "d": 3}, {"b": 5, "c": 3, "d":3}, {"a": 22, "b": "25"}]

我首先计算响应中存在的键的并集:

common_keys = set(k for r in response for k in r)

现在我只想用这些键作为字段名称来编写字典。当密钥不在特定字典中时,有一个默认值(空):

import csv

with open("out.csv","w",newline="") as f:
    cw = csv.DictWriter(f,fieldnames=sorted(common_keys),restval="",delimiter="\t")
    cw.writeheader()
    cw.writerows(response)

我明白了:

a       b       c       d
1       2               3
        5       3       3
22      25

编辑:仅当responselist时才有效,因此您必须首先转换为list

response = list(response)

如果这需要太多内存,那么,由于在没有遍历整个列表的情况下无法计算密钥的并集,唯一的选择是将响应行转储到文件中(例如:json在计算密钥的并集时,然后再次读取以创建csv文件。