Python将嵌套循环转换为列表理解

Python将嵌套循环转换为列表理解,python,list-comprehension,Python,List Comprehension,我有多层次的字典列表,我需要从中列出两个必要的列表。目前我可以这样做,但我想做一个完整的列表理解方式 poi = [] nh = [] tr_poi_nh = response.xpath('string(//body)').re(r'window\.__WEB_CONTEXT__=(.*?);\(this')[0] tr_poi_nh = json.loads(tr_poi_nh.replace("pageManifest", '"pageManifest&

我有多层次的字典列表,我需要从中列出两个必要的列表。目前我可以这样做,但我想做一个完整的列表理解方式

poi = [] 
nh = [] 
tr_poi_nh = response.xpath('string(//body)').re(r'window\.__WEB_CONTEXT__=(.*?);\(this')[0]

tr_poi_nh = json.loads(tr_poi_nh.replace("pageManifest", '"pageManifest"'))

for entry in tr_poi_nh['pageManifest']['hydrations']:   
    if entry['package'] == 'e374ol':       
        for value in entry['props']['initialAvailableFilters']:         
            if value['paramName'] =='distFrom':     
                poi = [x['normalized_name']  for x in value['poiSet']]   
            if value['paramName'] == 'zfn':                         
                nh = [y['label']  for y in value['choices']]

print(poi,nh)
    

我同意g.d.d.c.的评论。非常需要代码可读性


另一方面,看起来您正在使用建议的方法覆盖
poi
nh
at

我猜这会给你一个更想要的方法:

poi = [] 
nh = [] 
tr_poi_nh = response.xpath('string(//body)').re(r'window\.__WEB_CONTEXT__=(.*?);\(this')[0]

tr_poi_nh = json.loads(tr_poi_nh.replace("pageManifest", '"pageManifest"'))

for entry in tr_poi_nh['pageManifest']['hydrations']:   
    if entry['package'] == 'e374ol':       
        for value in entry['props']['initialAvailableFilters']:         
            if value['paramName'] =='distFrom':     
                poi.extend([x['normalized_name']  for x in value['poiSet']])
            if value['paramName'] == 'zfn':                         
                nh.extend([y['label']  for y in value['choices']])

print(poi,nh)

通过使用extend,您可以将所有值添加到原始列表中,而不是覆盖整个列表。

我同意g.d.d.c的意见。非常需要代码可读性


另一方面,看起来您正在使用建议的方法覆盖
poi
nh
at

我猜这会给你一个更想要的方法:

poi = [] 
nh = [] 
tr_poi_nh = response.xpath('string(//body)').re(r'window\.__WEB_CONTEXT__=(.*?);\(this')[0]

tr_poi_nh = json.loads(tr_poi_nh.replace("pageManifest", '"pageManifest"'))

for entry in tr_poi_nh['pageManifest']['hydrations']:   
    if entry['package'] == 'e374ol':       
        for value in entry['props']['initialAvailableFilters']:         
            if value['paramName'] =='distFrom':     
                poi.extend([x['normalized_name']  for x in value['poiSet']])
            if value['paramName'] == 'zfn':                         
                nh.extend([y['label']  for y in value['choices']])

print(poi,nh)

通过使用extend,您可以将所有值添加到原始列表中,而不是覆盖整个列表。

正如g.d.d.c所述,列表理解并不总是有利的。在这种情况下,它将具有更好的性能,因为您将避免在每次迭代时调用
append
,如所述。如果你充分利用缩进,你仍然可以很容易地理解列表


唯一的问题是,不能从列表理解返回两个不同的列表,最接近的方法是返回一个包含
(poi,nh)
对的列表,其中
poi
nh
是列表

您的问题中不清楚的另一个考虑因素是,您是否希望
附加
扩展
每个列表

  • 追加将产生一个列表列表,在某些用例中很有用,在这种情况下,您可以通过构建列表理解来提高性能
  • 如果您只关心所有元素,而不考虑源,那么扩展将导致一个平面列表。在这种情况下,如果数据的大小介于中到小之间,最好保持循环的原样,避免进一步分离元组(见下文)
不管怎样,这是一份清单。您可以首先判断它基本上是最内部的代码,然后是所有的
for
s和
if
s

main_list = [
    (
        [x['normalized_name']  for x in value['poiSet']]
            if value['paramName'] == 'distFrom' else []
        ,
        [y['label']  for y in value['choices']]
            if value['paramName'] == 'znf' else []
    )
    for entry in tr_poi_nh['pageManifest']['hydrations']  
    if entry['package'] == 'e374ol'
    for value in entry['props']['initialAvailableFilters']
]
我会考虑从这里开始哪种方法最简单,或者使用
main_list
原样并修改进一步的代码,或者将元组分成两个列表


如果必须将
poi
nh
作为两个单独的列表,则现在需要两个列表理解

# to have lists of lists
poi = [x[0] for x in main_list]
nh = [x[1] for x in main_list]

# OR
# to have flat lists
poi = [e for x in main_list for e in x[0]]
nh = [e for x in main_list for e in x[1]]

正如g.d.d.c所提到的,列表理解并不总是有利的。在这种情况下,它将具有更好的性能,因为您将避免在每次迭代时调用
append
,如所述。如果你充分利用缩进,你仍然可以很容易地理解列表


唯一的问题是,不能从列表理解返回两个不同的列表,最接近的方法是返回一个包含
(poi,nh)
对的列表,其中
poi
nh
是列表

您的问题中不清楚的另一个考虑因素是,您是否希望
附加
扩展
每个列表

  • 追加将产生一个列表列表,在某些用例中很有用,在这种情况下,您可以通过构建列表理解来提高性能
  • 如果您只关心所有元素,而不考虑源,那么扩展将导致一个平面列表。在这种情况下,如果数据的大小介于中到小之间,最好保持循环的原样,避免进一步分离元组(见下文)
不管怎样,这是一份清单。您可以首先判断它基本上是最内部的代码,然后是所有的
for
s和
if
s

main_list = [
    (
        [x['normalized_name']  for x in value['poiSet']]
            if value['paramName'] == 'distFrom' else []
        ,
        [y['label']  for y in value['choices']]
            if value['paramName'] == 'znf' else []
    )
    for entry in tr_poi_nh['pageManifest']['hydrations']  
    if entry['package'] == 'e374ol'
    for value in entry['props']['initialAvailableFilters']
]
我会考虑从这里开始哪种方法最简单,或者使用
main_list
原样并修改进一步的代码,或者将元组分成两个列表


如果必须将
poi
nh
作为两个单独的列表,则现在需要两个列表理解

# to have lists of lists
poi = [x[0] for x in main_list]
nh = [x[1] for x in main_list]

# OR
# to have flat lists
poi = [e for x in main_list for e in x[0]]
nh = [e for x in main_list for e in x[1]]

把每件事都列成清单并不总是有利的。此代码最好保持原样-列表理解将不清晰或不容易阅读。
poi
nh
在每次迭代中都会被覆盖。。。你的意思是
poi=[]
然后
poi.append(…
)?将所有内容都列为列表理解并不总是有利的。此代码最好保持原样-列表理解将不清晰或易于阅读。
poi
nh
在每次迭代中都会被覆盖…你的意思是
poi=[]
然后是
poi.append(…