代码之家  ›  专栏  ›  技术社区  ›  Ramón J Romero y Vigil

如何从Python3中的生成器列表中采样?

  •  1
  • Ramón J Romero y Vigil  · 技术社区  · 6 年前

    给予 list 属于 generator 价值观:

    from itertools import repeat
    
    ones_gen = repeat(1)
    
    twos_gen = repeat(2)
    
    threes_gen = repeat(3)
    
    gen_list = [ones_gen, twos_gen, threes_gen]
    

    如何创建另一个生成器,从列表中采样,以交错底层原始生成器中的值?

    1 2 3 1 2 3 1 2 3... .

    注意:这是一个可以通过 cycle([1,2,3]) ,但这只是一个例子。

    2 回复  |  直到 6 年前
        1
  •  2
  •   Patrick Haugh    6 年前

    使用 chain.from_iterable 具有 zip

    >>> cc = chain.from_iterable(zip(*gen_list))
    >>> next(cc)
    1
    >>> next(cc)
    2
    >>> next(cc)
    3
    >>> next(cc)
    1
    >>> next(cc)
    2
    >>> next(cc)
    3
    

    itertools recipes .

        2
  •  1
  •   Martijn Pieters    6 年前

    如果生成器的长度都相同(包括无限长),则可以 chain together zip() :

    from itertools import chain
    
    chain.from_iterable(zip(*gen_list))
    

    roundrobin() example from the itertools documentation :

    from itertools import cycle, islice
    
    def roundrobin(*iterables):
        "roundrobin('ABC', 'D', 'EF') --> A D E B F C"
        # Recipe credited to George Sakkis
        num_active = len(iterables)
        nexts = cycle(iter(it).__next__ for it in iterables)
        while num_active:
            try:
                for next in nexts:
                    yield next()
            except StopIteration:
                # Remove the iterator we just exhausted from the cycle.
                num_active -= 1
                nexts = cycle(islice(nexts, num_active))
    

    后者的演示:

    >>> from itertools import repeat, islice
    >>> ones_gen = repeat(1)
    >>> twos_gen = repeat(2)
    >>> limited_threes_gen = islice(repeat(3), 2)  # just two values
    >>> rrgen = roundrobin(ones_gen, twos_gen, limited_threes_gen)
    >>> next(rrgen)
    1
    >>> next(rrgen)
    2
    >>> next(rrgen)
    3
    >>> next(rrgen)
    1
    >>> next(rrgen)
    2
    >>> next(rrgen)
    3
    >>> next(rrgen)
    1
    >>> next(rrgen)
    2
    >>> next(rrgen)
    1
    

    3号发电机用完了,但另外两台发电机还在继续运转。