代码之家  ›  专栏  ›  技术社区  ›  Brent.Longborough

如何在列表理解中使用重匹配对象

  •  38
  • Brent.Longborough  · 技术社区  · 15 年前

    我有一个函数从字符串列表中挑选块并将它们作为另一个列表返回:

    def filterPick(lines,regex):
        result = []
        for l in lines:
            match = re.search(regex,l)
            if match:
                result += [match.group(1)]
        return result
    

    有没有办法把它重新定义为一个列表理解?很明显这是相当清楚的;只是好奇而已。


    感谢那些贡献的人,特别是@alex。下面是我的总结;regex match方法作为一个“预提升”参数传递给filterpick:

    import re
    
    def filterPick(list,filter):
        return [ ( l, m.group(1) ) for l in list for m in (filter(l),) if m]
    
    theList = ["foo", "bar", "baz", "qurx", "bother"]
    searchRegex = re.compile('(a|r$)').search
    x = filterPick(theList,searchRegex)
    
    >> [('bar', 'a'), ('baz', 'a'), ('bother', 'r')]
    
    4 回复  |  直到 12 年前
        1
  •  68
  •   Alex Martelli    15 年前
    [m.group(1) for l in lines for m in [regex.search(l)] if m]
    

    “诀窍”是 for m in [regex.search(l)] 部分——这就是您如何在列表理解中“分配”一个需要多次使用的值——只添加这样一个子句,对象在包含要“分配”给它的一个值的单个项列表上“迭代”。有些人认为这在风格上有点可疑,但我有时觉得它很实用。

        2
  •  10
  •   Ignacio Vazquez-Abrams    15 年前
    return [m.group(1) for m in (re.search(regex, l) for l in lines) if m]
    
        3
  •  7
  •   Wolph    15 年前

    可以缩短一点

    def filterPick(lines, regex):
        matches = map(re.compile(regex).match, lines)
        return [m.group(1) for m in matches if m]
    

    你可以把这一切放在一行,但这意味着你必须每行匹配两次,这样效率会低一些。

        4
  •  -13
  •   waldi    12 年前
    >>> "a" in "a visit to the dentist" 
    True 
    >>> "a" not in "a visit to the dentist" 
    False
    

    这也适用于您在列表中搜索的搜索查询

    ` p='a','b','c'

    p中的“b”返回true