繁体   English   中英

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

[英]Python convert nested loop to 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"'))

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)
    

我同意 gddc 的评论。 非常需要代码可读性。

另一方面,您似乎使用建议的方法覆盖了poinh 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)

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

正如 gddc 所提到的,列表理解并不总是有利的。 在这种情况下,它将具有更好的性能,因为您将避免在每次迭代时调用append ,如本答案所述 如果你充分利用缩进,你仍然可以有一个易于阅读的列表理解。

唯一的问题是,您不能从列表推导式中返回两个不同的列表,最接近的是返回具有(poi, nh)对的单个列表,其中poinh是列表。

您的问题中不清楚的另一个考虑因素是您是否要appendextend每个列表。

  • 附加将产生一个列表列表,在某些用例中很有用,在这种情况下,您绝对可以通过构建列表理解提高性能
  • 如果您只关心所有元素而不管来源如何,扩展将产生一个平面列表。 在这种情况下,如果数据大小适中,您最好保持循环不变并避免进一步分离元组的步骤(见下文)

无论如何,这里是列表理解。 你可以说它基本上是最里面的代码,然后是所有的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使用main_list并修改更多代码,要么将元组分成两个列表。

如果您必须将poinh作为两个单独的列表,那么您现在需要两个列表推导式。

# 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]]

暂无
暂无

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

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