如何将此 python 循环转换为列表理解?
How to transform this python loop into a list comprehension?
没关系。如 juanpa.arrivillaga 所示,列表理解不 return 字典 ><
上下文
我有以下 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": ""
}
}
输出
{'_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
回复中:
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
相反,您想检查 value 是一个字典,然后对其进行递归。但这对你没有多大帮助。我不够聪明,无法想出一种方法来使用递归和字典理解来展平像这样的嵌套字典。
没关系。如 juanpa.arrivillaga 所示,列表理解不 return 字典 ><
上下文
我有以下 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": ""
}
}
输出
{'_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
回复中:
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
相反,您想检查 value 是一个字典,然后对其进行递归。但这对你没有多大帮助。我不够聪明,无法想出一种方法来使用递归和字典理解来展平像这样的嵌套字典。