在列表推导中捕获匹配点'

时间:2015-07-30 05:34:43

标签: python list-comprehension

有时我会遇到我想捕捉其中的匹配点的情况 例如,在这一部分中的理解:

for child1 in node1.getChildren():
    if child1.getData() in [child2.getData() for child2 in node2.getChildren()]:
        # somehow I want the list comprehension to side effect and capture child2 match point
        doNodes(child1, child2)
        # Or if we capture an index:
        doNodes(child1, node2.getChild(idx)
    else:
        doOther()

有没有办法做到这一点(捕获child2或其索引)而不打开node2的另一个循环 - 甚至使用compresensions以外的东西。

换句话说:我们只是想缩短内部循环以避免更长的代码并使用标志来测试循环匹配。

注意:可能与此类似:Finding the index of elements based on a condition using python list comprehension

2 个答案:

答案 0 :(得分:2)

我想你需要:

for child1 in node1.getChildren():
    for child2_idx, child2 in enumerate(node2.getChildren()):
        if child1.getData() == child2.getData():
            doNodes(child1, child2_idx, child2)
            break
    else:
        doOther()

else循环中没有break时,for部分将被执行。例如。何时找不到匹配的child2

答案 1 :(得分:1)

怎么样 -

for child1 in node1.getChildren():
    c1data, c2index = next(((child2.getData(),i) for i, child2 in enumerate(node2.getChildren()) if child2.getData() == child1.getData()) , (None,None))
    if c1data:
        # get child2 using the index above - c2index
        doNodes(child1, child2)

这将返回匹配的第一个索引。

说明 -

  1. 我们创建一个生成器函数,返回child2的索引和数据,其中满足child2.getData() == child1.getData()条件。

  2. 然后我们将该生成器函数传递给next()方法,并指定如果生成器没有返回下一个值(即抛出StopIteration),我们应该返回(None, None)。 / p>

  3. 然后我们检查c1data是否为None。如果其None表示没有匹配的值,则匹配的值和匹配的索引位于变量c2index

  4. 示例/演示 -

    >>> l1 = [1,2,3,4,5]
    >>> l2 = [6,7,4,8,9]
    >>> cd,cidx = next(((x,i) for i,x in enumerate(l2) if x == l1[3]), (None,None))
    >>> cd
    4
    >>> cidx
    2
    >>> cd,cidx = next(((x,i) for i,x in enumerate(l2) if x == l1[4]), (None,None))
    >>> print(cd)
    None
    >>> print(cidx)
    None