简体   繁体   中英

Pythonic way to check nested keys in dict

I'm listening a webhook that have the following structure:

{
"date": "17-11-2021"
"chatStarted": {
   "info": "0219302139",
   "chat_id": "123"

},
"messages": {
   "receivedMessage": {
      "text": "hi",
      "chat_id": "123"
},
   "sentMessage": {
      "text": "hello",
      "chat_id": "123"
}
},
"chatEnded": {
   "info": "0219302139",
   "chat_id": "123"
}
}

The keys chatStarted , receivedMessage , sentMessage and chatEnded are all optional, except that should be at least one of them, and chatStarted and chatEnded can't come together.

Some examples

1) When a chat starts:

{
"date": "17-11-2021"
"chatStarted": {
   "info": "0219302139",
   "chat_id": "123"


},
"messages": {
   "receivedMessage": {
      "text": "hi",
      "chat_id": "123"
}
}
}

2) When a chat ends:

{
"date": "17-11-2021"
"chatEnded": {
   "info": "0219302139",
   "chat_id": "123"

},
"messages": {
   "sentMessage": {
      "text": "bye",
      "chat_id": "123"
}
}
}

3) Random conversation

{
"date": "17-11-2021"
"messages": {
   "receivedMessage": {
      "text": "hi",
      "chat_id": "123"
},
   "sentMessage": {
      "text": "hello",
      "chat_id": "123"
}
}
}

What i want to do:

I would like to check if those keys exists to put the key on file name with chat_id.

Example:

if a received chatStarted and receivedMessage my file name will be:

123.chatStarted.receivedMessage.json

123 = chat_id (inside all keys).

I would like to know the pythonic way to do so, i'm currently using:


file_name = ''

if 'chatStarted' in r:
    
     x = r['chatStarted']['chat_id']
     file_name.join('chatStarted', '.')

if 'chatEnded' in r:
    
     x = r['chatEnded']['chat_id']
     file_name.join('chatEnded', '.')
    

if 'messages' in r:
    
    try: 
        x = r['messages']['receivedMessage']['chat_id']
        file_name.join('receivedMessage', '.')
    except:
        print('No receivedMessage')

    try: 
        x = r['messages']['sentMessage']['chat_id']
        file_name.join('sentMessage', '.')
    except:
        print('No sentMessage')

With python, there are often many ways to handle a problem.

Here are some examples where you can check if the key exists in your object:

r = {
    'date': '17-11-2021',
     'messages': {
         'receivedMessage': {'text': 'hi', 'chat_id': '123'},
        'sentMessage': {'text': 'hello', 'chat_id': '123'}
     }
}

if 'messages' in r and 'receivedMessage' in r['messages'] and 'chat_id' in r['messages']['receivedMessage']:
    x = r['messages']['receivedMessage']['chat_id']
    print(x) # 123

val = r.get('messages', {}).get('receivedMessage', {}).get('chat_id', None)
if val:
    x = val
    print(x) # 123
    
def custom_get(my_dict, *keys):
    val = my_dict
    for key in keys:
        try:
            val = val[key]
        except KeyError:
            return None
    return val

val = custom_get(r, 'messages', 'receivedMessage', 'chat_id')
if val:
    x = val
    print(x) # 123

If you have a complex object structure, an easier solution is to use a library like jsonpath-ng .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM