最后使用附加项获取成对迭代器

时间:2016-01-02 03:18:12

标签: python python-3.x iterator itertools

目标:例如给定有限迭代器p0, p1, ..., pn转为(p0, p1), (p1, p2), ..., (pn-1, pn), (pn, None) - 迭代器通过成对的具有特殊最后项的连续项。

pairwise()函数作为itertools用法的示例存在于文档中:

def pairwise(iterable):
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = tee(iterable)
    next(b, None)
    return zip(a, b)

但是我想另外在迭代器的末尾添加另一个项目(如果它是有限的),并且对第二个元素的某个默认值(例如,None)。

如何有效实施此附加功能?

3 个答案:

答案 0 :(得分:6)

使用itertools.zip_longest

    function check() {
      var w1 = document.getElementById("wordOne");
      var w2 = document.getElementById("wordTwo");
      if (w1 == "Jesus" && w2 == "wept.") {
        document.getElementById("feedack").innerHTML = "Well done!";
      } else {
        document.getElementById("feedback").innerHTML = "Please try again.";
      }
    }

当其中一个输入迭代器用完时,<div> <input type="text" id="wordOne"> <input type="text" id="wordTwo"> <br> <input type="button" id="evaluate" value="Click to check" onclick="check()"> <br> <h2 id="feedback"></h2> </div>会用填充值填充它,默认值为def pairwise(iterable): "s -> (s0,s1), (s1,s2), (s2, s3), ..." a, b = tee(iterable) next(b, None) return zip_longest(a, b)

答案 1 :(得分:1)

至于最后添加(sn, None),正如user2357112已经回答的那样,你可以使用zip_longest,因此一个已经用尽的迭代器并没有停止整个序列(所以a迭代器可以仍然产生最后一个元素。)

对于所有其他情况,例如如果你想在最后添加更多元素,你可以自己创建一个生成器函数。所有itertools函数都是惰性生成器,只有在请求结果中的下一个元素时才会生成新结果,并且您可以轻松地从生成器中使用它们。

比方说,您需要pairwise在最后产生一个标记值(None, None),然后您可以简单地从zip_longest产生结果,然后产生另一个项目:

def example (iterable):
    a, b = tee(iterable)
    next(b, None)
    yield from zip_longest(a, b)
    yield (None, None)

{3.3}实际上带有yield from语法。对于早期版本,尤其是Python 2,您需要通过循环遍历项目并再次生成它们来手动执行此操作:

def example (iterable):
    a, b = tee(iterable)
    next(b, None)
    for x in zip_longest(a, b):
        yield x
    yield (None, None)

答案 2 :(得分:0)

您可以创建一个生成器:

def pairwise(iterable, additional=None):
    iterable = iter(iterable)
    first, second = next(iterable), next(iterable)
    while 1:
        yield first,second
        try:
            first,second = second, next(iterable)
        except TypeError:
            yield second, additional
            break

结果:

>>> list(pairwise([1,2,3], 'a'))
[(1, 2), (2, 3), (3, 'a')]
>>> list(pairwise('abc', 'a'))
[('a', 'b'), ('b', 'c'), ('c', 'a')]
>>> list(pairwise('abcd', 'a'))
[('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]

对于无限可迭代:

>>> a = pairwise(infi(), 6)
>>> for i in range(10):
...     print(next(a))
...
(0, 1)
(1, 2)
(2, 3)
(3, 0)
(0, 1)
(1, 2)
(2, 3)
(3, 0)
(0, 1)
(1, 2)