为了账号安全,请及时绑定邮箱和手机立即绑定

Python 请求:处理 JSON 响应、存储到列表或字典?

Python 请求:处理 JSON 响应、存储到列表或字典?

繁星点点滴滴 2022-07-19 15:08:39
我正在使用 python 请求库从 api 获取数据。数据以称为消息的大型 json 数组返回。其中包含许多单独的“消息”子级别 jsons(请参阅底部的 json 响应示例)。在这个 json 响应中,对于每条消息,我只关心几个(2 或 3)个数据点。我需要获取这几个数据点,并将它们存储到某些东西(列表列表、字典等)中,以便以后可以引用它,存储到一个对象并从另一个函数中使用。我需要存储的数据点是id,conversationId和body. The id is unique, while theconversationId` 在对话中的所有消息之间共享,因此不是唯一的。我首先想问一下您认为实现这一目标的最佳方法是什么。我猜是列表列表还是列表字典?我太新了,不知道哪个是更好的解决方案。此外,无论选择什么方法,我都需要知道如何引用它们并通过 id 调用它们以从另一个函数存储到对象。我还没有弄清楚如何成功地做到这一点。以下是我尝试过的一些事情,只是为了大致了解如何做到这一点:response=requests.get(url + id, headers=h, params=p)messages=json.loads(response.text)for message in messages:    print(message['body'])^^ 在这里我只是想看看我是否可以引用特定消息的正文,没有工作。r=requests.get(url + id, headers=h, params=p)inbound_dict = {}inbound=json.loads(r.text)for item in inbound['messages']:    inbound_dict[item['conversationId']] = item['body']print(inbound_dict)^^ 这个确实有点作用,但不允许我有效地组织数据以便稍后调用。当我打印字典时,它会显示最新的值,因为键不是唯一的......所以它是覆盖而不是附加。这就是让我觉得最好列出清单的原因。最后,我想要一个解决方案,将数据组织conversationId在字典或类似结构中的类似结构中,我可以通过conversationId、 或引用消息msgId,以及一种简洁易读的方式来存储所有数据......:)Messages     |___                  msgId:         |_conversationId-[         |                 body         |                 msgId:         |_conversationId-[         |                 body         |                 msgId:         |_conversationId-[                           body最后,这是一个 json 示例。请记住,我仍在学习和掌握 python 的速度。谢谢大家的时间!
查看完整描述

3 回答

?
开心每一天1111

TA贡献1836条经验 获得超13个赞

您可以使用这样的组合列表和字典理解来做到这一点:


import json

from pprint import pprint



response = b'{"id":1005672,"messages":[{"id":4461048,"body":"Mnow test test","conversationId":1005672,"locationId":2045,"contactId":12792806,"assignedUserId":0,"status":"RECEIVED","error":null,"kind":"INCOMING","outgoing":false,"reviewRequest":false,"type":"SMS","readDate":0,"respondedDate":0,"sentDate":1576783232355,"attachments":[]},{"id":4461049,"body":"THIS NUMBER DOES NOT CURRENTLY ACCEPT TEXT MESSAGES PLEASE CALL (716) 444-4444 TO WORK WITH ONE OF OUR INTAKE SPECIALISTS","conversationId":1005672,"locationId":2045,"contactId":12792806,"assignedUserId":0,"status":"RECEIVED","error":null,"kind":"AUTO_RESPONSE","outgoing":true,"reviewRequest":false,"type":"SMS","readDate":0,"respondedDate":0,"sentDate":1576783233546,"attachments":[]},{"id":4620511,"body":"test sms,test sms","conversationId":1005672,"locationId":2045,"contactId":12792806,"assignedUserId":17297,"status":"DELIVERED","error":null,"kind":"API","outgoing":true,"reviewRequest":false,"type":"SMS","readDate":0,"respondedDate":0,"sentDate":1577987093930,"attachments":[]}]}'


data = json.loads(response)


messages = [

    {'id': message['id'],

     'conversationId': message['conversationId'],

     'body': message['body']} for message in data['messages']

]


pprint(messages, sort_dicts=False)

输出:


[{'id': 4461048, 'conversationId': 1005672, 'body': 'Mnow test test'},

 {'id': 4461049,

  'conversationId': 1005672,

  'body': 'THIS NUMBER DOES NOT CURRENTLY ACCEPT TEXT MESSAGES PLEASE CALL '

          '(716) 444-4444 TO WORK WITH ONE OF OUR INTAKE SPECIALISTS'},

 {'id': 4620511, 'conversationId': 1005672, 'body': 'test sms,test sms'}]

您可以使处理更加数据驱动,并消除理解中的大量重复编码,从而使其更加简洁,如下所示:


import json

from pprint import pprint


data_points = 'id', 'conversationId', 'body'

response = b'{"id":1005672,"messages":[{"id":4461048,"body":"Mnow test test","conversationId":1005672,"locationId":2045,"contactId":12792806,"assignedUserId":0,"status":"RECEIVED","error":null,"kind":"INCOMING","outgoing":false,"reviewRequest":false,"type":"SMS","readDate":0,"respondedDate":0,"sentDate":1576783232355,"attachments":[]},{"id":4461049,"body":"THIS NUMBER DOES NOT CURRENTLY ACCEPT TEXT MESSAGES PLEASE CALL (716) 444-4444 TO WORK WITH ONE OF OUR INTAKE SPECIALISTS","conversationId":1005672,"locationId":2045,"contactId":12792806,"assignedUserId":0,"status":"RECEIVED","error":null,"kind":"AUTO_RESPONSE","outgoing":true,"reviewRequest":false,"type":"SMS","readDate":0,"respondedDate":0,"sentDate":1576783233546,"attachments":[]},{"id":4620511,"body":"test sms,test sms","conversationId":1005672,"locationId":2045,"contactId":12792806,"assignedUserId":17297,"status":"DELIVERED","error":null,"kind":"API","outgoing":true,"reviewRequest":false,"type":"SMS","readDate":0,"respondedDate":0,"sentDate":1577987093930,"attachments":[]}]}'

data = json.loads(response)

messages = [{dp: message.get(dp) for dp in data_points}

                for message in data['messages']]


pprint(messages, sort_dicts=False)


查看完整回答
反对 回复 2022-07-19
?
红颜莎娜

TA贡献1842条经验 获得超12个赞

我的理解是,您希望您的消息采用可通过对话检索的数据结构。这是我要做的:


from pprint import pprint


#with this data structure whenever we refer to a conversation, if it

#doesn't exist, it gets created

from collections import defaultdict

inbound_dict = defaultdict(dict) 


inbound=json.loads(data)

for item in inbound['messages']:

    print (item)


    current_conversation=inbound_dict[item['conversationId']]

    #inbound_dict retrives the apropriate conversation,

    #   or creates a new one for us to fill

    current_conversation[item["id"]] = item['body'] #add our item to it.


    #or if there's a chance we might want *everything* else about the

    #message later even if just the date in order to preserve

    #conversation ordering or whatever:


    #currentconversation[item["id"]] = item


pprint(inbound_dict)

但这可能是矫枉过正,这取决于你以后要做什么处理,以及它是什么处理。如果您只是让他们选择一个对话,并显示最后 20 条消息,那么可切片的列表可能是内部数据结构的最佳选择,在这种情况下,我会这样做:


from pprint import pprint


#with this data structure whenever we refer to a conversation, if it

#doesn't exist, it gets created

from collections import defaultdict

inbound_dict = defaultdict(list) 


inbound=json.loads(data)

for item in inbound['messages']:

    print (item)


    current_conversation=inbound_dict[item['conversationId']]

    #inbound_dict retrives the apropriate conversation,

    #   or creates a new one for us to fill


    current_conversation.append(

        (item["id"], item['body'])

        ) # here we add our item to it, in this case a tuple of id and body


    #or if there's a chance we might want *everything* else about the

    #message later even if just the date in order to preserve

    #conversation ordering or whatever:


    #currentconversation.append(item)


pprint(inbound_dict)

基本相同的操作,但 defaultdict 为我们提供了不同类型的内部集合来填充。


查看完整回答
反对 回复 2022-07-19
?
幕布斯7119047

TA贡献1794条经验 获得超8个赞

如果您可以拥有多个具有相同会话 ID 的项目,那么您可以执行以下操作:


r=requests.get(url + id, headers=h, params=p).json()

inbound_dict = {}

for item in r['messages']:

    conv_id = item['conversationId']

    if conv_id not in inbound_dict:

        inbound_dict[conv_id]=[{'msg_id' : item['id'], 'body' : item['body']}]

    else:

        inbound_dict[conv_id].append({'msg_id' : item['id'], 'body' : item['body']})


print(inbound_dict)

生成的数据结构是一个以 conversation_id 作为键的字典,每个 conversation_id 映射到一个list项目dict。每个项目都存储特定消息的 message_id 和正文。然后,您可以通过检索为 conv_id 键存储的消息列表来迭代特定对话的消息。


或者,您可以选择以下数据结构进行映射: {conv_id -> { message_id : {message info ...}, ...}.


这可以像这样实现:


r=requests.get(url + id, headers=h, params=p).json()

inbound_dict = {}

for item in r['messages']:

    conv_id = item['conversationId']

    if conv_id not in inbound_dict:

        inbound_dict[conv_id]={item['id'] : {'msg_id' : item['id'], 'body' : item['body']}}

    else:

        inbound_dict[conv_id][item['id']] = {'msg_id' : item['id'], 'body' : item['body']}


print(inbound_dict)


在这种情况下,如果您知道 con_id 和 message_id,则可以直接从对话中访问消息。


所以它真的取决于这个数据结构的下游实用程序。


请注意,上述内容也可以通过列表推导来完成。


查看完整回答
反对 回复 2022-07-19
  • 3 回答
  • 0 关注
  • 110 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信