2014-04-16 32 views
11

所以,我有一個3元組的迭代,它是懶惰生成的。我試圖找出如何將它變成3個迭代器,分別由元組的第一,第二和第三個元素組成。不過,我希望這樣做是懶惰的。在Python中懶洋洋地轉換一個列表

因此,例如,我希望[(1, 2, 3), (4, 5, 6), (7, 8, 9)]變成[1, 4, 7][2, 5, 8][3, 6, 9]。 (除了我想迭代列表以外)

標準zip(*data)成語不起作用,因爲參數解包會擴展整個迭代。 (您可以通過注意zip(*((x, x+1, x+2) for x in itertools.count(step=3)))掛起驗證這一點。)

我已經想出了迄今爲止最好的是以下幾點:

def transpose(iterable_of_three_tuples): 
    teed = itertools.tee(iterable_of_three_tuples, 3) 
    return map(lambda e: e[0], teed[0]), map(lambda e: e[1], teed[1]), map(lambda e: e[2], teed[2]) 

這似乎是工作。但它幾乎不像乾淨的代碼。它做了很多似乎是不必要的工作。

+1

'izip'? –

+0

由於你有工作代碼,你可能從代碼審查中得到更好的結果 – wnnmaw

+0

你如何期望你的新迭代器從第三個元組中獲得'7'而不消耗整個外迭代?如果你在'count'這樣的無限迭代器上嘗試,'tranpose'也會掛起。 – BrenBarn

回答

3

你的transpose幾乎是你所需要的。

如果您選擇了任何解決方案,您必須緩衝未使用的值(例如,以獲得7,您必須讀取1-6,並將它們存儲在內存中,以便其他迭代器要求它們時)。 tee已經做了這種緩衝,所以沒有必要自己實施。

其他唯一的(未成年人)的事情是,我會寫略有不同,避免了maplambda S:從`itertools`模塊

def transpose(iterable_of_three_tuples): 
    teed = itertools.tee(iterable_of_three_tuples, 3) 
    return (e[0] for e in teed[0]), (e[1] for e in teed[1]), (e[2] for e in teed[2]) 
相關問題