Python嵌套forloop列表理解

时间:2015-10-19 18:14:36

标签: python

我试图将这个工作嵌套的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)]

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

3 个答案:

答案 0 :(得分: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 ]

答案 1 :(得分:1)

嵌套循环对于列表推导并不是一个真正的问题,因为你也可以在那里嵌套:

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

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

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

请注意,我在这里使用生成器表达式:它们与列表推导基本相同,但不要将完整结果创建为列表,而是一次只生成元素。因此,如果您只想逐个使用它(这是这种情况),它会更有效率。毕竟,你只对列表推导的结果感兴趣,所以理解将消耗生成器表达式。

答案 2 :(得分:0)

我会做这样的事情:

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