2014-09-13 49 views
2

如果我做的:有沒有辦法在python中更改get的yield的處理順序?

def foo(): 
    yield from range(0,10) 
    yield from range(10,20) 

for num in foo(): 
    print(num) 

我從0到19 沒有改變的範圍功能輸入一個有序列表,有沒有一種簡單的方法來指定,我想的是進了名單:0, 10,1,11,2,12 ...

基本上我首先想要每個發生器的第一個元素。比我想要的每個發電機的第二個元素,然後是第三個等。

積分: 有沒有辦法改變它,以便當發電機產生不等數量的結果時,第二個發電機在第一個發電機完成後產生剩餘的結果?

回答

7

您正在嘗試zip()您的迭代器;明確地這樣做:

from itertools import chain 

def foo(): 
    yield from chain.from_iterable(zip(range(10), range(10, 20))) 

採用itertools.chain.from_iterable()讓你繼續在這裏使用yield from,不上不下的元組zip()產生。

演示:

>>> from itertools import chain 
>>> def foo(): 
...  yield from chain.from_iterable(zip(range(10), range(10, 20))) 
... 
>>> list(foo()) 
[0, 10, 1, 11, 2, 12, 3, 13, 4, 14, 5, 15, 6, 16, 7, 17, 8, 18, 9, 19] 

如果你有不同長度的發電機,可以使用itertools.zip_longest()

from itertools import zip_longest 

def foo(): 
    yield from (i for pair in zip_longest(range(10), range(10, 22)) 
        for i in pair if i is not None) 

我在這裏使用了不同的扁平化技術在發電機表達雙環。

這一切都變得單調而乏味,因爲你沒有使用yield from與另一發生器(所以你不需要爲generator.send()generator.throw()支持傳播),你可能也只是使這是一個適當的循環:

def foo(): 
    for x, y in zip_longest(range(10), range(10, 22)): 
     if x is not None: 
      yield x 
     if y is not None: 
      yield y    

您還可以使用在itertools documentation recipies section列出的roundrobin()配方:

from itertools import cycle 

def roundrobin(*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() 
     except StopIteration: 
      pending -= 1 
      nexts = cycle(islice(nexts, pending)) 

def foo(): 
    yield from roundrobin(range(10), range(10, 22)) 
+0

如果什麼發生器有不同的長度?這個解決方案似乎默默忘記了鏈條的其餘部分。我寧願我仍然休息。 – Christian 2014-09-13 14:15:59

+1

@Christian:然後使用['itertools.zip_longest'](https://docs.python.org/3/library/itertools.html#itertools.zip_longest),可能會過濾出'None'值。但是你必須明確地*這樣做*。 – 2014-09-13 14:17:19

+0

@MartijnPieters我想我以前曾經說過這個,但是......從文檔中找到'roundrobin',也許呢? ¹http://stackoverflow.com/a/23874310/1763356 – Veedrac 2014-09-13 18:52:51

相關問題