【问题标题】:Capturing match point 'in' list comprehensions在列表推导中捕获匹配点
【发布时间】:2015-07-30 05:34:43
【问题描述】:

有时我会遇到想要在其中捕获匹配点的情况 一个理解,例如,在这个片段中:

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

【问题讨论】:

  • 为什么不想打开另一个循环?你已经有两个循环了。
  • 没有“理解中的匹配点”。列表推导返回一个列表。您想获得与child1 相同数据的第一个child2 吗?可以有多个吗?
  • @minitech:我们知道这一点,但我只是在询问可能的副作用或其他一些避免内部循环的技术。

标签: python list-comprehension


【解决方案1】:

我猜你需要:

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 部分将在 for 循环中没有 break 时执行。例如。当找不到匹配的child2 时。

【讨论】:

    【解决方案2】:

    这样的事情怎么样 -

    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)

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


    示例/演示 -

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

    【讨论】:

      猜你喜欢
      • 2018-10-30
      • 2015-05-15
      • 2014-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-23
      相关资源
      最近更新 更多