itertools.chain, чтобы связать список iter? - PullRequest
8 голосов
/ 08 марта 2011
import itertools
def _yield_sample():
    it = iter(itertools.combinations('ABCD', 2))
    it2 = iter(itertools.combinations('EFGH', 3))
    itc = itertools.chain(it,it2)
    for x in itc:
        yield x

def main():
    for x in _yield_sample():
        print x

Это работает для печати комбинаций.

>>> 
('A', 'B')
('A', 'C')
('A', 'D')
...

Но это:

def __position_combination(_count = [2,3,4,5]):
    its = []
    for ct in _count:
        it = iter(itertools.combinations('ABCDEFG', ct))
        its.append(it)
    itc = itertools.chain(its)
    for x in itc:
        yield x

def main():
    for x in __position_combination():
        print x

не будет, будет распечатано

>>> 
<itertools.combinations object at 0x02179210>
<itertools.combinations object at 0x02179240>
<itertools.combinations object at 0x02179270>

Я должен переписать код, чтобы он работал как требуется.

itc = itertools.chain(*its)

Вот мой вопрос:

itertools.chain(iter, iter, iter)  vs    itertools.chain(*[iter,iter,iter])

Чем они отличаются? Согласно документации itertools.chain делает:

def chain(*iterables):
    # chain('ABC', 'DEF') --> A B C D E F
    for it in iterables:
        for element in it:
            yield element

Итак, почему itertools.chain(iter, iter, iter) также работает здесь?
Означает ли это iter, iter, iter = *(iter, iter, iter)?

Ответы [ 2 ]

15 голосов
/ 08 марта 2011
4 голосов
/ 08 марта 2011

означает ли это iter, iter, iter = * (iter, iter, iter)?

Не само по себе. Распаковка аргумента работает только при вызове функции, поэтому следующие два вызова эквивалентны:

f(1,2,3)
f(*[1,2,3])

Но *[1,2,3] не скомпилируется, если это не часть вызова. Вы можете смешивать обычные (позиционные) аргументы с неупакованными:

f(1,*[2,3])

так что вышеизложенное также эквивалентно двум предыдущим вызовам.

...