繁体   English   中英

如何将此 python 循环转换为列表理解?

[英]How to transform this python loop into a list comprehension?

没关系。 如 juanpa.arrivillaga 所示,列表理解不返回字典 ><

语境

我有以下 python 代码(参见下一段代码)。 我想尝试优化它以比较常规循环和列表理解之间的执行时间。

常规循环版本

def flatten_json( nested_dict, flattened_dict={}, superior_level_key: str = ""):

    for key, value in nested_dict.items():
        if type(nested_dict[key]) is dict:
            flattened_dict = flatten_json(
                nested_dict[key], flattened_dict, "{}_".format(key))
        else:
            flattened_dict['{}{}'.format(superior_level_key, key)] = value

    return flattened_dict


import json

with open('json.json') as j:
    d = json.load(j)
    print(flatten_json(d, {}, ""))

当前的,失败的,列表理解版本

def flatten_json(nested_dict, flattened_dict={}, superior_level_key: str = ""):

    return [flatten_json(nested_dict[key], flattened_dict, "{}_".format(key))
            if type(nested_dict) is dict
            else value for key, value in nested_dict.items()]


import json

with open('json.json') as j:
    d = json.load(j)
    print(flatten_json(d, {}, ""))

错误

列表理解版本引发以下错误:

Traceback (most recent call last):
  File "p1.py", line 13, in <module>
    print(flatten_json(d, {}, ""))
  File "p1.py", line 3, in flatten_json
    return [flatten_json(nested_dict[key], flattened_dict, "{}_".format(key))
  File "p1.py", line 3, in <listcomp>
    return [flatten_json(nested_dict[key], flattened_dict, "{}_".format(key))
  File "p1.py", line 5, in flatten_json
    else value for key, value in nested_dict.items()]
AttributeError: 'float' object has no attribute 'items'

问题

为什么会抛出该错误以及如何解决?

输入

{
    "_score": 1.0,
    "_index": "sirene_prod",
    "_id": "AXSp612eur2DngRir4BH",
    "_type": "sirene_prod",
    "_source": {
        "enseigne": "",
        "codpos": {
            "cp": "17300",
            "bur_distrib": "300",
            "depet": "17"
        },
        "id": "ddf9e5b2aa0099ff6934a3d83b1678f64e27859e377362ef8682a9b1",
        "l3_normalisee": "",
        "apet700": "10.71C",
        "sigle": "",
        "siren": "793120569",
        "libapen": "Boulangerie et boulangerie-patisserie",
        "apen700": "10.71C",
        "cedex": "",
        "typvoie": "AV",
        "numvoie": 33,
        "nom": "",
        "depet_limit": [
            "16",
            "24",
            "33",
            "79",
            "85"
        ],
        "libcom": "ROCHEFORT",
        "l2_normalisee": {
            "text": "",
            "nom": "",
            "initial": ""
        },
        "libvoie": "GAMBETTA",
        "nic": "00017",
        "prenom": "",
        "nomen_long": {
            "text": "LA PASSION DU PAIN",
            "nom": "LA PASSION DU PAIN",
            "initial": "LPDP"
        },
        "indrep": ""
    }
}

Output

{'_score': 1.0, '_index': 'sirene_prod', '_id': 'AXSp612eur2DngRir4BH', '_type': 'sirene_prod', '_surce_enseigne': '', 'codpos_cp': '17300', 'codpos_bur_distrib': '300', 'codpos_depet': '17', '_soure_id': 'ddf9e5b2aa0099ff6934a3d83b1678f64e27859e377362ef8682a9b1', '_source_l3_normalisee': '', '_surce_apet700': '10.71C', '_source_sigle': '', '_source_siren': '793120569', '_source_libapen': 'Bouangerie et boulangerie-patisserie', '_source_apen700': '10.71C', '_source_cedex': '', '_source_typvie': 'AV', '_source_numvoie': 33, '_source_nom': '', '_source_depet_limit': ['16', '24', '33', '79' '85'], '_source_libcom': 'ROCHEFORT', 'l2_normalisee_text': '', 'l2_normalisee_nom': '', 'l2_normamalisee_initial': '', '_source_libvoie': 'GAMBETTA', '_source_nic': '00017', '_source_prenom': '', renom': '', 'nomen_long_text': 'LA PASSION DU PAIN', 'nomen_long_nom': 'LA PASSION DU P_long_initiaAIN', 'nomen_long_initial': 'LPDP', '_source_indrep': ''}

这是一个迭代解决方案,它应该比您当前的递归解决方案更快:

def flatten_json_iterative(nested):
    flattened = {}
    stack = [(nested, "")]
    push_to_stack = stack.append
    pop_from_stack = stack.pop
    while stack:
        nested_dict, superior_key = pop_from_stack()
        for key, value in nested_dict.items():
            if isinstance(value, dict):
                push_to_stack((value, f"{key}_"))
            else:
                flattened[f"{superior_key}{key}"] = value
    return flattened

在repl中:

In [8]: flatten_json_iterative(data)
Out[8]:
{'_score': 1.0,
 '_index': 'sirene_prod',
 '_id': 'AXSp612eur2DngRir4BH',
 '_type': 'sirene_prod',
 '_source_enseigne': '',
 '_source_id': 'ddf9e5b2aa0099ff6934a3d83b1678f64e27859e377362ef8682a9b1',
 '_source_l3_normalisee': '',
 '_source_apet700': '10.71C',
 '_source_sigle': '',
 '_source_siren': '793120569',
 '_source_libapen': 'Boulangerie et boulangerie-patisserie',
 '_source_apen700': '10.71C',
 '_source_cedex': '',
 '_source_typvoie': 'AV',
 '_source_numvoie': 33,
 '_source_nom': '',
 '_source_depet_limit': ['16', '24', '33', '79', '85'],
 '_source_libcom': 'ROCHEFORT',
 '_source_libvoie': 'GAMBETTA',
 '_source_nic': '00017',
 '_source_prenom': '',
 '_source_indrep': '',
 'nomen_long_text': 'LA PASSION DU PAIN',
 'nomen_long_nom': 'LA PASSION DU PAIN',
 'nomen_long_initial': 'LPDP',
 'l2_normalisee_text': '',
 'l2_normalisee_nom': '',
 'l2_normalisee_initial': '',
 'codpos_cp': '17300',
 'codpos_bur_distrib': '300',
 'codpos_depet': '17'}

顺便提一句:

您的方法不起作用,因为您正在检查nested_dict是否是dict然后对其进行递归, if type(nested_dict) is dict而不是,您将要检查该是否是 dict,然后对其进行递归。 但这对你帮助不大。 我不够聪明,无法想出一种使用递归的方法,例如,dict理解来展平这样的嵌套字典。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM