简体   繁体   English

检查dict中嵌套键的Pythonic方法

[英]Pythonic way to check nested keys in dict

I'm listening a webhook that have the following structure:我正在听一个具有以下结构的 webhook:

{
"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.chatStartedreceivedMessagesentMessagechatEnded都是可选的,除了应该至少是其中之一,并且 chatStarted 和 chatEnded 不能放在一起。

Some examples一些例子

1) When a chat starts: 1) 聊天开始时:

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


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

2) When a chat ends: 2) 聊天结束时:

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

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

3) Random conversation 3) 随机对话

{
"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.我想检查这些密钥是否存在,以便将密钥放在带有 chat_id 的文件名上。

Example:例子:

if a received chatStarted and receivedMessage my file name will be:如果收到chatStartedreceivedMessage我的文件名将是:

123.chatStarted.receivedMessage.json 123.chatStarted.receivedMessage.json

123 = chat_id (inside all keys). 123 = chat_id(在所有键中)。

I would like to know the pythonic way to do so, i'm currently using:我想知道这样做的pythonic方式,我目前正在使用:


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.对于 python,通常有很多方法可以处理问题。

Here are some examples where you can check if the key exists in your object:以下是一些示例,您可以检查 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 .如果你有一个复杂的 object 结构,一个更简单的解决方案是使用像jsonpath-ng这样的库。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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