当前位置: 代码迷 >> python >> Python嵌套的forloop列表理解
  详细解决方案

Python嵌套的forloop列表理解

热度:24   发布时间:2023-06-13 15:00:39.0

我正在尝试将此工作嵌套的forloop转换为单行列表理解&我似乎无法使其正常工作。 伪代码如下:

result = []
for x in something:
    for y in x.address:
       m = re.search("some pattern to match",y)
       if m:
         result += [m.group(1)]

关于如何解决这个问题的任何指示?

您将需要一个生成器表达式。

matches = ( re.search(r'some pattern to match', y) for x in something
                                                     for y in x.address  )
result = [ m.group(1) for m in matches if m ]

嵌套循环并不是列表理解的真正问题,因为您也可以将其嵌套在其中:

lst = []
for y in z:
    for x in y:
        lst.append(f(x))

这转化为以下列表理解:

[f(x) for y in z for x in y]

您可以轻松地将其继续进行多个级别。

决定是否要向列表中添加内容的条件也可以正常工作:

lst = []
for x in y:
    if t(x):
        lst.append(f(x))

这转换为以下带有过滤器的列表理解:

[f(x) for x in y if t(x)]

当然,您也可以将其与多个级别结合使用。


现在,什么某种问题的,虽然是当你要首先执行的东西,那么就这个结果进行过滤,并追加的东西,要看结果。 天真的解决方案是将函数调用移入其中,并执行两次:

rexpr = re.compile('some pattern to match')
[rexpr.search(y).group(1) for x in something for y in x.address if rexpr.search(y)]

但这显然会两次运行您通常希望避免的搜索。 在这一点上,您可以使用一些我通常不建议使用的骇人听闻的解决方案(因为它们会损害可读性)。 由于您的结果仅取决于正则表达式搜索的结果,因此您还可以分两个步骤解决此问题:首先,搜索每个元素并将它们映射到match对象,然后对那些匹配项进行过滤并只返回有效的那些:

[m.group(1) for m in (rexpr.search(y) for x in something for y in x.address) if m]

请注意,我在这里使用生成器表达式:这些表达式基本上与列表推导相同,但不会将完整结果创建为列表,而是一次仅在元素上屈服。 因此,如果您只想一一消耗(在这种情况下),则效率更高。 毕竟,您只对列表推导的结果感兴趣,因此推导将消耗生成器表达式。

我会做这样的事情:

# match function
def match(x):
    m  = re.search("some pattern to match",x)
    if m:
        return m.group(1)
    else:
        return None

#list comprehension     
results = [match(y) for x in something for y in x.address if match(y)]