'Removing element from list of nested dictionaries [closed]

I have the following list:

raw_data = raw_data = [{'type': 'message',
  'subtype': 'bot_message',
  'text': "This content can't be displayed.",
  'ts': '1650899428.077709',
  'username': 'Typeform',
  'icons': {'image_01': 'www.example.com/foo.png'},
  'bot_id': 'BPD1K2SJW',
  'app_id': 'AD6SC3RT6',
  'blocks': [{'type': 'section',
    'block_id': 'Smd',
    'text': {'type': 'mrkdwn',
     'text': 'You have a new response.',
     'verbatim': False}},
   {'type': 'section',
    'block_id': '6YaLt',
    'text': {'type': 'mrkdwn',
     'text': '*Where did you first hear about us?*\nOnline Search',
     'verbatim': False}},
   {'type': 'section',
    'block_id': 'w3o',
    'text': {'type': 'mrkdwn',
     'text': '*Direction: *\nNorth',
     'verbatim': False}},
   {'type': 'section',
    'block_id': 'PTQ',
    'text': {'type': 'mrkdwn',
     'text': '*Location? *\nNew York',
     'verbatim': False}},
   {'type': 'section',
    'block_id': 'JCfSP',
    'text': {'type': 'mrkdwn',
     'text': '*What can we do better? *\nTo Nothing',
     'verbatim': False}},
   {'type': 'section',
    'block_id': 'aATCO',
    'text': {'type': 'mrkdwn',
     'text': '*What is your age? *\n32',
     'verbatim': False}},
   {'type': 'section',
    'block_id': 'FbB',
    'text': {'type': 'mrkdwn',
     'text': '*Can we speak with you?*\nNo',
     'verbatim': False}},
   {'type': 'section',
    'block_id': 'GR+=',
    'text': {'type': 'mrkdwn',
     'text': '*Order Number:*\n123456',
     'verbatim': False}},
   {'type': 'actions',
    'block_id': '71Q',
    'elements': [{'type': 'button',
      'action_id': '+hZp',
      'text': {'type': 'plain_text', 'text': 'View results', 'emoji': True},
      'url': 'www.example.com/form/abcd/results'}]},
   {'type': 'section',
    'block_id': 'RJOA',
    'text': {'type': 'mrkdwn', 'text': ' ', 'verbatim': False}}]},

 {'type': 'message',
  'subtype': 'channel_join',
  'ts': '1650897264.344889',
  'user': 'U03CTDZ4MA6',
  'text': '<@T19CTAB4MA6> has joined the channel',
  'inviter': 'T049HGBCW'},
            
{'type': 'message',
  'subtype': 'bot_message',
  'text': "This content can't be displayed.",
  'ts': '1650899428.077709',
  'username': 'Typeform',
  'icons': {'image_01': 'www.example.com/foo.png'},
  'bot_id': 'BPD1K2SJW',
  'app_id': 'AD6SC3RT6',
  'blocks': [{'type': 'section',
    'block_id': 'Smd',
    'text': {'type': 'mrkdwn',
     'text': 'You have a new response.',
     'verbatim': False}},
   {'type': 'section',
    'block_id': '6YaLt',
    'text': {'type': 'mrkdwn',
     'text': '*Where did you first hear about us?*\nOnline Search',
     'verbatim': False}},
   {'type': 'section',
    'block_id': 'w3o',
    'text': {'type': 'mrkdwn',
     'text': '*Direction: *\nNorth',
     'verbatim': False}},
   {'type': 'section',
    'block_id': 'PTQ',
    'text': {'type': 'mrkdwn',
     'text': '*Location? *\nNew York',
     'verbatim': False}},
   {'type': 'section',
    'block_id': 'JCfSP',
    'text': {'type': 'mrkdwn',
     'text': '*What can we do better? *\nTo Nothing',
     'verbatim': False}},
   {'type': 'section',
    'block_id': 'aATCO',
    'text': {'type': 'mrkdwn',
     'text': '*What is your age? *\n32',
     'verbatim': False}},
   {'type': 'section',
    'block_id': 'FbB',
    'text': {'type': 'mrkdwn',
     'text': '*Can we speak with you?*\nNo',
     'verbatim': False}},
   {'type': 'section',
    'block_id': 'GR+=',
    'text': {'type': 'mrkdwn',
     'text': '*Order Number:*\n123456',
     'verbatim': False}},
   {'type': 'actions',
    'block_id': '71Q',
    'elements': [{'type': 'button',
      'action_id': '+hZp',
      'text': {'type': 'plain_text', 'text': 'View results', 'emoji': True},
      'url': 'www.example.com/form/abcd/results'}]},
   {'type': 'section',
    'block_id': 'RJOA',
    'text': {'type': 'mrkdwn', 'text': ' ', 'verbatim': False}}]}
           
]

I would like to be able to drop the following from this list:

 {'type': 'message',
  'subtype': 'channel_join',
  'ts': '1650897264.344889',
  'user': 'U03CTDZ4MA6',
  'text': '<@T19CTAB4MA6> has joined the channel',
  'inviter': 'T049HGBCW'},

I do not want to drop by index because this block can be anywhere is the list (which contains hundreds of elements).

I'm using the following:

trimmed = [[elem for elem in dat['type'] if elem['type']['subtype'] != 'channel_join'] for dat in raw_data]

Which gives me a TypeError:

TypeError: string indices must be integers

What is the best way to do this?

Thanks!



Solution 1:[1]

Use the filter() function:

def myfilter(item):
    if item.get('type') == 'message' and item.get('subtype') == 'channel_join':
        return False
    return True

filtered_data = list(filter(myfilter, raw_data))
print(len(raw_data))
print(len(filtered_data))

Or as a list comp:

filtered_data = [x for x in raw_data if myfilter(x)]

The main problem in your code is this: elem['type']['subtype']

elem['type'] is the string "message", and that string has no element named 'subtype'

Solution 2:[2]

This should work fine if you want to use list comprehension.

drop =  {'type': 'message',
  'subtype': 'channel_join',
  'ts': '1650897264.344889',
  'user': 'U03CTDZ4MA6',
  'text': '<@T19CTAB4MA6> has joined the channel',
  'inviter': 'T049HGBCW'}
  
  
data = [x for x in raw_data if(x!=drop)]

print(data)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Jhanzaib Humayun