我现有的代码使用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
答案 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
编辑:仅当response
为list
时才有效,因此您必须首先转换为list
:
response = list(response)
如果这需要太多内存,那么,由于在没有遍历整个列表的情况下无法计算密钥的并集,唯一的选择是将响应行转储到文件中(例如:json
在计算密钥的并集时,然后再次读取以创建csv
文件。