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



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

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所提到的,列表理解并不总是有利的。在这种情况下,它将具有更好的性能,因为您将避免在每次迭代中调用append,正如这个答案所解释的那样。如果你很好地利用了缩进,你仍然可以很容易地理解列表。

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

你的问题中没有明确的另一个考虑因素是,你想在每个列表中使用append还是extend

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

无论如何,这是列表理解。你可以看出它基本上是最内部的代码,然后是所有的forif

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并修改进一步的代码,要么将元组分离为两个列表。

如果必须将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]]

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

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

我猜这会给你一个更受欢迎的方法:

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,您将把所有值添加到原始列表中,而不是覆盖整个列表。

最新更新