简体   繁体   中英

How do I leverage an index with list comprehension?

I am trying to filter a JSON array based on a value contained in each of the arrays. Provided some user input, I only want to return relevant values based on the type.

Sample json:

{
    "routes": [
        {
            "name": "Golden Shower",
            "type": "Boulder",
            "rating": "V5",
            "stars": 5,
            "starVotes": 131,
            "pitches": ""
        },
        {
            "name": "Girls Only",
            "type": "Sport",
            "rating": "5.10a",
            "stars": 4.9,
            "starVotes": 156,
            "pitches": "1"
        }
    ],
    "success": 1
}

I have attempted to use a few variations of a code sample provided on a similar question, but am running in to issues due to slightly more complex data structure. See: how to filter json array in python

I have tried a few variations of code. All of the errors center around improper use of indices. Some things I've tried.

routeData = routesByGpsResp.json()
input_dict = routeData
output_dict = [x for x in input_dict if x['type'] == 'Sport']

error: sting indices must be integers

output_dict = [x for x in input_dict.items() if ['routes'][x]['type'] == 'Sport']

error: list indices must be integers or slices, not tuple

I was able to print a list of route names using for statement an index, but cannot seem to figure it out for list comprehension.

for key in range(len(routeData['routes'])):
    print(routeData['routes'][key]['name'])

Is list comprehension the wrong way to go here? Should I be using a for statement instead?

Any help is appreciated!

Note: all your attempts are list comprehensions , while the variable name suggests a dict comprehension ( [Python]: PEP 274 -- Dict Comprehensions ).

Here's an example how you could get output_dict (and below, output_list ) based on your input_dict , and the condition(s). As a note: the dict comprehension nests a list comprehension (which alone constitutes the 2 nd example) for the "routes" key, while for all the other keys leaves the values unchanged:

 >>> output_dict = {k: v if k != "routes" else [i for i in v if i["type"] == "Sport"] for k, v in input_dict.items()} >>> >>> from pprint import pprint >>> >>> pprint(output_dict) {'routes': [{'name': 'Girls Only', 'pitches': '1', 'rating': '5.10a', 'starVotes': 156, 'stars': 4.9, 'type': 'Sport'}], 'success': 1} >>> >>> # Or if you only want the list ... >>> output_list = [i for i in input_dict.get("routes", list()) if i["type"] == "Sport"] >>> >>> pprint(output_list) [{'name': 'Girls Only', 'pitches': '1', 'rating': '5.10a', 'starVotes': 156, 'stars': 4.9, 'type': 'Sport'}] 

In your first attempt:

output_dict = [x for x in input_dict if x['type'] == 'Sport']

x in input_dict iterates over the keys, so you are doing "routes"['type'] , but strings are indexes by integers, and not by a string, hence the error string indices must be integers

In your second attempt:

output_dict = [x for x in input_dict.items() if ['routes'][x]['type'] == 'Sport']

['routes'] is a list, and x is a tuple of ( key,value ) obtained by iterating over the dictionary input_dict , so ['routes'][x] raises a error: list indices must be integers or slices, not tuple

The right way for a list-comprehension, as already pointed out by @cs95, is to iterate over the list of routes by for x in input_dict.get('routes') , get the dictionary for the value of key type that matches Sport

print([x for x in input_dict.get('routes') if x.get('type') == 'Sport'])

The output is

[{'name': 'Girls Only', 'type': 'Sport', 'rating': '5.10a', 'stars': 4.9, 'starVotes': 156, 'pitches': '1'}]

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