'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 |
