2012-02-13 3 views
1

У меня есть список lg генераторов, lg = [g1, g2, ..., gn]. Эти генераторы объединяются в один генератор с izip, G = izip(*lg). Один из генераторов в lg (скажем, g1) обычно построен сам по izip, поэтому его сгенерированный результат появляется как кортеж при итерации по G. Тем не менее, мне нужен пакет, который распакован, т. Е. При итерации более G, G должен генерировать кортеж без вложенных кортежей. Возможно ли до unpack g1, когда СтроительствоG?izip внутри izip: распаковывать генераторы?

Edit: Пример (версия shortend от @jsbueno):

from itertools import izip 

g1 = izip(xrange(1,3), xrange(3,5)) 
g2 = xrange(10, 13) 
g3 = xrange(20, 23) 

lg = [g1, g2, g3] 

for i in izip(*lg): 
    print i 

производит

((1, 3), 10, 20) 
((2, 4), 11, 21) 

, но мне нужно

(1, 3, 10, 20) 
(2, 4, 11, 21) 

ответ

1

Так как для того, что вы хотите "izip" нуждается в информации об итераторах внутри внутреннего izips - и izip непрозрачен по отношению к этому (т. е. вы не можете вывести аргументы в izip, заданный объектом izip). Один из способов - переопределить функциональность izip, но в известном ей виде - и если результат, полученный одним из прошедших итераторов, является кортежем, конкатенировать его с результатами, вместо того, чтобы добавлять его в единый товар:

class FlatIzip(object): 
    def __init__(self, *args): 
     self.generators = args 
    def __iter__(self): 
     iters = [iter(x) for x in self.generators] 
     while True: 
      result = [] 
      for iterator in iters: 
       element = iterator.next() 
       if isinstance(element, tuple): 
        result += list(element) 
       else: 
        result.append(element) 
      yield tuple(result) 

#Example: 

from itertools import izip 

g1 = xrange(10) 
g2 = xrange(10,20) 
g3 = xrange(20, 30) 
g4 = izip(xrange(40,50), xrange(50,60)) 


lg = [g1, g2, g3, g4] 

for x in FlatIzip(*lg): 
    print x 
Смежные вопросы