将json对象中的特定名称-值对顺序追加到csv文件中



我得到了以下按时间排序的JSON:

{'quotes': [{'t': '2021-07-06T13:45:00.005216368Z', 'ax': 'H', 'ap': 359.52, 'as': 2, 'bx': 'U', 'bp': 359.51, 'bs': 2, 'c': ['R']}, {'t': '2021-07-06T13:45:00.00533471Z', 'ax': 'H', 'ap': 359.52, 'as': 2, 'bx': 'Q', 'bp': 359.51, 'bs': 2, 'c': ['R']}, {'t': '2021-07-06T13:45:00.005559387Z', 'ax': 'H', 'ap': 359.52, 'as': 2, 'bx': 'Q', 'bp': 359.51, 'bs': 3, 'c': ['R']}, {'t': '2021-07-06T13:45:00.006669818Z', 'ax': 'P', 'ap': 359.53, 'as': 3, 'bx': 'Q', 'bp': 359.51, 'bs': 3, 'c': ['R']}, {'t': '2021-07-06T13:45:00.008649561Z', 'ax': 'P', 'ap': 359.53, 'as': 3, 'bx': 'Q', 'bp': 359.51, 'bs': 4, 'c': ['R']}], 'code': 'Q1QQ', 'next_page_token': None}

我正在尝试添加"t"one_answers";bp"到CSV文件,并保持这些名称-值对的顺序相同。使用上面的例子,文件看起来像这样:

"t", "bp"     
2021-07-06T13:45:00.005216368Z, 359.51
2021-07-06T13:45:00.00533471Z, 359.51
2021-07-06T13:45:00.005559387Z, 359.51
2021-07-06T13:45:00.006669818Z, 359.51 
2021-07-06T13:45:00.008649561Z, 359.51    

这是我的尝试,它工作,但似乎相当慢:

from json import dumps, loads
from requests import get
response = dumps(get(url = 'https://***', params = {***}.json()['results'])
cycle = [0]
while cycle[-1] < len(loads(response)):
print(loads(response)[cycle[-1]]['t'], ',', loads(response)[cycle[-1]]['bp'], file = open(file = 'specific_name_pairs.csv', mode ='a'))
cycle.append(cycle[-1] + 1)

有没有更有效的/"pythonic"如何做到这一点?提前感谢您的时间!

csv模块提供了一个dictwwriter类,可用于将dict对象序列化为csv记录。

关于代码的几个问题:
  • 每次运行一个循环时对响应进行反序列化
  • 文件在每次循环运行时打开,并留下许多文件句柄打开。

您可以通过:

  • 在进入循环之前反序列化JSON响应内容
  • 使用上下文管理器打开文件,以便在块中的语句执行后正确关闭文件
  • 确保使用csv模块正确序列化对象

import csv
from requests import get
response = get(url = 'https://***', params = {***})
response_lst = response.json()
quotes =  response_lst['quotes']
with open('specific_name_pairs.json', mode='w') as csv_file:
csv_writer = csv.DictWriter(csv_file, delimiter=',', fieldnames=['t', 'bp'])
csv_writer.writeheader()
for item in quotes:
record = {'t': item['t'], 'bp': item['bp']}
csv_writer.writerow(record)

您需要对变量TESTING、URL、PARAMS和OUTPUTFILE进行适当的更改。否则,这就能满足你们的要求了我希望你们能从中得到启发。与之前的答案不同,我选择不使用CSV模块,因为在我看来,对于这种简单的情况,它是多余的。

import requests

TESTING = True
URL = 'https://foo'
PARAMS = {}
OUTPUTFILE = '/Users/andy/specific_name_pairs.csv'
SAMPLE = {'quotes': [{'t': '2021-07-06T13:45:00.005216368Z', 'ax': 'H', 'ap': 359.52, 'as': 2, 'bx': 'U', 'bp': 359.51, 'bs': 2, 'c': ['R']},
{'t': '2021-07-06T13:45:00.00533471Z', 'ax': 'H', 'ap': 359.52,'as': 2, 'bx': 'Q', 'bp': 359.51, 'bs': 2, 'c': ['R']},
{'t': '2021-07-06T13:45:00.005559387Z', 'ax': 'H', 'ap': 359.52, 'as': 2, 'bx': 'Q', 'bp': 359.51, 'bs': 3, 'c': ['R']}]}


def getdata():
if TESTING:
return SAMPLE
else:
r = requests.get(URL, PARAMS)
r.raise_for_status()
return r.json()


def process():
data = getdata()
with open(OUTPUTFILE, 'w') as outfile:
outfile.write('"t", "bp"n')
for j in data['quotes']:
outfile.write(f'{j["t"]}, {j["bp"]}n')


if __name__ == '__main__':
process()

最新更新