捕获匹配点 'in' 列表理解

Capturing match point 'in' list comprehensions

有时我会遇到想捕捉比赛点的情况 理解,例如,在这个部分:

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 打开另一个循环 - 即使使用压缩以外的东西。

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

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

怎么样 -

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)

这 return 是它们匹配的第一个索引。

解释-

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

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

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


Example/Demo -

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

我猜你需要:

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

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