2012-08-22 62 views
9

我想enumerate類似功能迭代器產生(previous_element, current_element)對。也就是說,考慮到iter大多數pythonic的方式來獲得以前的元素

i0, i1, i1, ... 

我想offset(iter)產生

(None, i0), (i0, i1), (i1, i2) ... 
+2

沒有「最pythonic」的方式。你會看到「更多pythonic」的方式(例如,使用函數而不是帶有兩個工廠類的類來創建第一類),但是「pythonic」是一個主觀的想法。 –

+6

點擊其中一個答案接受它。 – lockstock

回答

0

最佳答案我有(這需要itertools)是

def offset(iter, n=1): 
    # returns tuples (None, iter0), (iter0, iter1), (iter1, iter2) ... 
    previous = chain([None] * n, iter) 
    return izip(previous, iter) 

,但我會感興趣的是看看是否有人有單線(或者比這個功能更好的名字)!

+1

這在迭代器上不能正常工作(與迭代器相反)。例如:'list(offset(i for i in xrange(10)))'return '[(None,0),(1,2),(3,4),(5,6),(7, 8)]'。 – Dougal

+0

這裏的總體思路很好,你只需要使用'tee'在給定的迭代器上創建2個獨立的迭代器。看到我的答案。 – Kos

2
def pairwise(iterable): 
    """s -> (s0,s1), (s1,s2), (s2, s3), ... 
    see http://docs.python.org/library/itertools.html 
    """ 
    a, b = itertools.tee(iterable) 
    b.next() 
    return itertools.izip(a, b) 

編輯移動文檔字符串到函數

+0

不給你'(None,i0)'第一對 – MattH

+1

@MattH易於修復;將'b.next()'行更改爲'yield(None,b.next())'(然後循環遍歷'izip'併產生,或者使用Python語法中的yield 3.3)。 – Dougal

+0

@MattH,是的,我知道。我想OP將能夠解決細節問題。此代碼來自文檔,被認爲是對現存問題的暗示。 – bpgergo

26

什麼簡單(明顯)解決方案?

def offset(iterable): 
    prev = None 
    for elem in iterable: 
     yield prev, elem 
     prev = elem 
+0

對我來說看起來不錯,估計我附近有一個非常相似的東西。 – MattH

+0

是的,這只是*太明顯... – sloth

+0

我不知道爲什麼每個人都跳過'itertools'這個。爲什麼使用大錘和鐵釘時,圖釘會做? – mgilson

8

要放在桌子上更itertools:

from itertools import tee, izip, chain 

def tee_zip(iterable): 
    a, b = tee(iterable) 
    return izip(chain([None], a), b) 
+0

+1我喜歡這個。 – jamylak

1
def offset(iter, n=1, pad=None): 
    i1, i2 = itertools.tee(iter) 
    i1_padded = itertools.chain(itertools.repeat(pad, n), i1) 
    return itertools.izip(i1_padded, i2) 

@bpgergo + @ user792036 =此。最好的兩個世界:)。

相關問題