Python 中的循环和条件

For loops and conditionals in Python

我是 Python 的新手,我想知道是否有办法 shorten/optimise 以下循环:

for breakdown in data_breakdown:
    for data_source in data_source_ids:
       for camera in camera_ids:
           if (camera.get("id") == data_source.get("parent_id")) and (data_source.get("id") == breakdown.get('parent_id')):
               for res in result:
                   if res.get("camera_id") == camera.get("id"):
                       res.get('data').update({breakdown.get('name'): breakdown.get('total')})

我试过这个 oneliner,但它似乎不起作用:

res.get('data').update({breakdown.get('name'): breakdown.get('total')}) for camera in camera_ids if (camera.get("id") == data_source.get("parent_id")) and (data_source.get("id") == breakdown.get('parent_id'))

您可以使用 itertools.product 为您处理嵌套循环,我认为(虽然我不确定,因为我看不到您的数据)您可以跳过所有 .get.update 并仅使用 [] 运算符:

from itertools import product

for b, d, c in product(data_breakdown, data_source_ids, camera_ids):
    if c["id"] != d["parent_id"] or d["id"] != b["parent_id"]:
        continue
    for res in result:
        if res["camera_id"] == c["id"]:
            res['data'][b['name']] = b['total']

如果有的话,要优化这些循环的 性能 ,您应该使它们更长且嵌套更多,data_source.get("id") == breakdown.get('parent_id') 发生在 [=13= 之外]循环。

但也许还有一个替代方案,您可以在其中更改数据的结构,这样您就不需要尽可能多地循环来查找匹配的 ID 值。将您当前的每个列表(字典)转换为一个字典,其键等于您将在该循环中尝试匹配的 'id' 值,并且该值为整个字典。

sources_dict = {source.get("id"): source for source in data_source_ids}
cameras_dict = {camera.get("id"): camera for camera in camera_ids}
results_dict = {res.get("camera_id"): res for res in result}

现在整个循环只需要一层:

for breakdown in data_breakdown:
    source = sources_dict[breakdown["parent_id"]]
    camera = cameras_dict[source["parent_id"]]
    res = results_dict[camera["id"]]
    res.data[breakdown["name"]] = breakdown["total"]

此代码假定您当前代码中带有 get 的所有查找都将成功获取值。您实际上并没有检查从 get 调用中获得的任何值是否为 None,因此它可能没有太大好处。

我还要指出,尚不清楚原始代码中的 camera 循环是否完全必要。您可能已经能够跳过它并直接将 data_source['parent_id']res['camera_id'] 进行比较,而无需将它们都与两者之间的 camera['id'] 进行比较。在我的更新版本中,这将转化为省略 cameras_dict 的创建并直接使用 source["parent_id"] 索引 results_dict 而不是首先索引以查找 camera