簡體   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