如何利用列表理解来利用索引?

时间:2019-05-19 18:39:36

标签: python json list-comprehension

我正在尝试根据每个数组中包含的值来过滤JSON数组。提供一些用户输入后,我只想根据类型返回相关值。

示例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
}

我尝试使用类似问题上提供的代码示例的一些变体,但由于数据结构稍微复杂一些,因此遇到了一些问题。参见:how to filter json array in python

我尝试了一些代码变体。所有错误都与索引使用不当有关。我尝试过的一些东西。

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

错误:字符串索引必须是整数

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

错误:列表索引必须是整数或切片,而不是元组

我能够使用for语句索引来打印路由名称列表,但是似乎无法弄清楚列表名称。

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

列表理解是去这里的错误方法吗?我应该使用for语句吗?

感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

请注意:您所有的尝试都是 list理解,而变量名表明 dict 理解({ {3}}。

这是一个示例,您可以根据您的 input_dict 和条件获取 output_dict (以下为 output_list )。注意: dict 理解为“ routes” <嵌套了一个 list 理解(仅构成第二个 nd 示例)< / em>键,而其他所有键的值均保持不变:

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

答案 1 :(得分:1)

第一次尝试:

const functions = require('firebase-functions');

const admin = require('firebase-admin');

admin.initializeApp(functions.config().firebase);

// // Create and Deploy Your First Cloud Functions
// // https://firebase.google.com/docs/functions/write-firebase-functions
//
// exports.helloWorld = functions.https.onRequest((request, response) => {
//  response.send("Hello from Firebase!");
// });

exports.notifyNewReport = functions.firestore
    .document('admin/reportsToReview')
    .onUpdate((change, context) => {
        console.log('Change to doc function registered');
      // Get an object representing the document
      const newValueReports = change.after.data().reports;

      // ...or the previous value before this update
      const previousValueReports = change.before.data().reports;


      if (newValueReports.length > previousValueReports.length) {
        console.log('Report added to review list');

        var adminsArray = ""

        admin.firestore()
            .collection('admin')
            .doc('admins')
            .get()
            .then(doc => {
                adminsArray = doc.data().admins
                return console.log('Found admin UID: ' + adminsArray);
            })
            .catch(error => {
                console.error(error);
                res.error(500);
            });


        //Code to get send notification to each device


        console.log("Construct the notification message.");
        var message = {
            notification: {
                body: 'There are new reports to review!',
            },
        token: token
        };

        admin.messaging().send(message)

      } 

    });

output_dict = [x for x in input_dict if x['type'] == 'Sport'] 遍历键,所以您正在做x in input_dict,但是字符串是整数而不是字符串的索引, 因此出现错误"routes"['type']

第二次尝试:

string indices must be integers

output_dict = [x for x in input_dict.items() if ['routes'][x]['type'] == 'Sport'] 是一个列表,['routes']是通过迭代字典x获得的(key,value)的元组,因此input_dict引发一个{ {1}}

@ cs95已经指出,列表理解的正确方法是通过['routes'][x]遍历路由列表,获取匹配键error: list indices must be integers or slices, not tuple的值的字典for x in input_dict.get('routes')

type

输出为

Sport