python 没有重复的 itertools 循环

python itertools round robin with no duplications

我在 https://docs.python.org/3.1/library/itertools.html
中成功修改了 roundrobin 的配方 包括限制(到达 X 元素时停止)- 下面的代码...

现在 - 我真正想要的是 "stop when reaching X elements but with no element duplication"。
有可能吗? (因为是发电机...)

def roundrobin(limit, *iterables):
    "roundrobin('ABC', 'D', 'EF') --> A D E B F C"
    # Recipe credited to George Sakkis
    pending = len(iterables)
    nexts = cycle(iter(it).next for it in iterables)
    while pending:
        try:
            for next in nexts:
                yield next()
                limit -= 1
                if limit == 0:
                    return

        except StopIteration:
            pending -= 1
            nexts = cycle(islice(nexts, pending))

调用它:

candidates = [['111', '222', '333'],['444','222','555']] 
list(roundrobin(4, *candidates))

我想得到:

['111,'444','222','333']

而不是:

['111,'444','222','222']

就像我正在使用当前代码一样

这是一种可能的实现方式 - 我在生成器函数中添加了一个名为 seenset,以跟踪我们已经 yield 编辑的元素。请注意,这意味着 all 中的元素 every iterable 必须是 hashable(如果它们达到),这不是基数的限制 roundrobin.

def roundrobin_limited_nodupe(limit, *iterables):
    """A round-robin iterator duplicates removed and a limit.

        >>> list(roundrobin_limited_nodupe(6, 'ABC', 'DB', 'EFG'))
        ['A', 'D', 'E', 'B', 'F', 'C']  # only six elements, only one 'B'

    Notes:
      - Recipe credited to George Sakkis

    """
    pending = len(iterables)
    seen = set()  # keep track of what we've seen
    nexts = cycle(iter(it).next for it in iterables)
    while pending:
        try:
            for next in nexts:
                candidate = next()
                if candidate not in seen:  # only yield when it's new
                    seen.add(candidate)
                    yield candidate
                    limit -= 1
                    if limit == 0:
                        return
        except StopIteration:
            pending -= 1
            nexts = cycle(islice(nexts, pending))