Nico
Nico

Reputation: 323

Python - Get all values of specific key

Im currently playing a bit with the twitter API. So far i managed to get a specific tweet as json and prettyprint that. Here is the output:

{
    "contributors": null,
    "coordinates": null,
    "created_at": "Sun Jun 28 12:32:35 +0000 2020",
    "display_text_range": [
        19,
        23
    ],
    "entities": {
        "hashtags": [],
        "symbols": [],
        "urls": [],
        "user_mentions": [
            {
                "id": 11883745733410470,
                "id_str": "11883745733410470",
                "indices": [
                    0,
                    10
                ],
                "name": "Account1",
                "screen_name": "account1"
            },
            {
                "id": 27822535,
                "id_str": "27822535",
                "indices": [
                    11,
                    18
                ],
                "name": "Account2",
                "screen_name": "account2"
            }
        ]
    },
    "favorite_count": 0,
    "favorited": false,
    "filter_level": "low",
    "geo": null,

How can i store all values of the key entities -> user_mentions -> screen_name in a variable, list, or whatever? I just want to store them and do something later on.

So far i got:

def on_data(self, data):
    # Twitter returns data in JSON format - we need to decode it first
    decoded = json.loads(data)
    #print(json.dumps(decoded, indent=4, sort_keys=True))
    tweet_id = decoded['id_str']
    username = decoded['user']['screen_name']
    text = decoded['text']
    is_reply = decoded['in_reply_to_status_id']
    mentions = decoded['entities']['user_mentions']['screen_name']

Which gives me an error because it returns more than one screen_name of course.

    mentions = decoded['entities']['user_mentions']['screen_name']
TypeError: list indices must be integers or slices, not str

Upvotes: 0

Views: 170

Answers (3)

furas
furas

Reputation: 142641

decoded['entities']['user_mentions'] is a list.

You can use type() to see it

print( type( decoded['entities']['user_mentions'] ) )

To get single name you have to use index [0], [1], and later ["screen_name"]

print( decoded['entities']['user_mentions'][0]["screen_name"] )

print( decoded['entities']['user_mentions'][1]["screen_name"] )

To get all of them you need for-loop

names = []

for item in decoded['entities']['user_mentions']:
    #print( item["screen_name"] )
    names.append(item["screen_name"])
    
print(names)  

or list comprehension

names = [item["screen_name"] for item in decoded['entities']['user_mentions']]

print(names)

Minimal working example

decoded = {
    "contributors": None,
    "coordinates": None,
    "created_at": "Sun Jun 28 12:32:35 +0000 2020",
    "display_text_range": [
        19,
        23
    ],
    "entities": {
        "hashtags": [],
        "symbols": [],
        "urls": [],
        "user_mentions": [
            {
                "id": 11883745733410470,
                "id_str": "11883745733410470",
                "indices": [
                    0,
                    10
                ],
                "name": "Account1",
                "screen_name": "account1"
            },
            {
                "id": 27822535,
                "id_str": "27822535",
                "indices": [
                    11,
                    18
                ],
                "name": "Account2",
                "screen_name": "account2"
            }
        ]
    },
    "favorite_count": 0,
    "favorited": False,
    "filter_level": "low",
    "geo": None,
}

print('--- single ----')

print( decoded['entities']['user_mentions'][0]["screen_name"] )    
print( decoded['entities']['user_mentions'][1]["screen_name"] )

print('--- for-loop ----')

names = []

for item in decoded['entities']['user_mentions']:
    print( item["screen_name"] )
    names.append(item["screen_name"])
    
print(names)

print('--- list comprehension ----')

names = [item["screen_name"] for item in decoded['entities']['user_mentions']]

print(names)

Upvotes: 0

Koen
Koen

Reputation: 306

The error gives you a good hint. decoded['entities']['user_mentions'] is a list, so you can get all screen names using:

for name in decoded['entities']['user_mentions']:
    # name['screen_name'] now is the name you want
    print(name['screen_name'])

If you want a long string of all screen names, or do various other thing you can also use list functions like join, as @Sushanth noticed.

Upvotes: 4

Vishal Singh
Vishal Singh

Reputation: 6234

screen_names = [
        screen_name["screen_name"] for screen_name in decoded["entities"]["user_mentions"]
    ]

decoded['entities']['user_mentions'] is a list, so you can only access it with indices.

def on_data(self, data):
    # Twitter returns data in JSON format - we need to decode it first
    decoded = json.loads(data)
    #print(json.dumps(decoded, indent=4, sort_keys=True))
    tweet_id = decoded['id_str']
    username = decoded['user']['screen_name']
    text = decoded['text']
    is_reply = decoded['in_reply_to_status_id']
    screen_names = [screen_name["screen_name"] for screen_name in decoded['entities']['user_mentions']]

Upvotes: 1

Related Questions