简体   繁体   English

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

[英]Python convert nested loop to list comprehension

I have multi level list of dictionary from which I need to make two required list.我有字典的多级列表,我需要从中制作两个必需的列表。 Currently I can do it this way but wanted to make fully list comprehension way,目前我可以这样做,但想以完整的列表理解方式,

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)
    

I agree with gddc's comment.我同意 gddc 的评论。 Code readability is highly wanted.非常需要代码可读性。

On another note, it looks like you're overriding poi and nh at with the suggested approach.另一方面,您似乎使用建议的方法覆盖了poinh at 。

I'm guessing this will give you a more wanted approach:我猜这会给你一个更想要的方法:

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)

By using extend you will add all of the values to your original list rather then override the entire list.通过使用扩展,您会将所有值添加到原始列表中,而不是覆盖整个列表。

As gddc mentioned it is not always the case that a list comprehension will be advantageous.正如 gddc 所提到的,列表理解并不总是有利的。 In this case it will have better performance because you will avoid calling append on each iteration, as explained by this answer .在这种情况下,它将具有更好的性能,因为您将避免在每次迭代时调用append ,如本答案所述 If you make good use of indentation you can still have a easily readable list comprehension.如果你充分利用缩进,你仍然可以有一个易于阅读的列表理解。

The only problem is, you cannot return two different lists from a list comprehension, the closest you could get is to return a single list with (poi, nh) pairs, where poi and nh are lists.唯一的问题是,您不能从列表推导式中返回两个不同的列表,最接近的是返回具有(poi, nh)对的单个列表,其中poinh是列表。

Another consideration which is not clear in your question is if you want to append or extend each list.您的问题中不清楚的另一个考虑因素是您是否要appendextend每个列表。

  • Appending will result in a list of lists, useful in some use cases, in which case you can definitely improve performance by building a list comprehension .附加将产生一个列表列表,在某些用例中很有用,在这种情况下,您绝对可以通过构建列表理解提高性能
  • Extending will result in a flat list, if you you only care about all elements regardless of the source.如果您只关心所有元素而不管来源如何,扩展将产生一个平面列表。 In this case, if the data is on the moderate-to-small size, you could be better off leaving the loop as it is and avoiding further steps to separate tuples (see below)在这种情况下,如果数据大小适中,您最好保持循环不变并避免进一步分离元组的步骤(见下文)

Anyway here is the list comprehension.无论如何,这里是列表理解。 You can tell it is basically the inner-most code first then all the for s and if s in order.你可以说它基本上是最里面的代码,然后是所有的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']
]

I would think about which is easiest from here, either to use main_list as it is and modify further code, or separate the tuples into two lists.我会考虑从这里开始哪个最简单,要么按main_list使用main_list并修改更多代码,要么将元组分成两个列表。

If you MUST have poi and nh as two separate lists, you now need two list comprehensions.如果您必须将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