2012-11-27 69 views
1

可能重複:
Python: Looping through all but the last item of a listPython的方法列表中的項目荏苒

說,我想通過列表進行迭代。每次迭代我都想用當前和下一個項來計算某些東西。我可以做類似

mylist = [1, 2, 3, 4] 
for i in range(len(mylist)): 
    try: 
     compute(mylist[i], mylist[i+1]) 
    except IndexError: 
     compute(mylist[i]) 

我還可以做

mylist = [1, 2, 3, 4] 
for num in mylist: 
    try: 
     compute(num, mylist[mylist.index(num)+1]) 
    except IndexError: 
     compute(num) 

這些都不顯得特別好。有沒有更pythonic的做法呢?

+2

您可以嘗試使用'pairwise'從食譜[itertools文檔](http://docs.python.org/2/library/itertools.html#recipes)。 – Wessie

+0

@Wessie:這正是他應該做的......你應該把它變成一個答案。 –

+0

爲什麼在最後一次迭代中只有一個參數調用'compute'? – Eric

回答

1

有三種方法可以做到這一點(雖然我可能會更喜歡第一個,除非你的條件是不同的):

  1. 使用itertools.izip() - 這將是有效的,並符合Python:

    for item1, item2 in itertools.izip(my_list, my_list[1:]): 
        # do something... 
    
  2. 使用enumerate()

    for index, item in enumerate(my_list): 
        # do something... 
    
  3. 商店前面的行中的變量(例如假設沒有None您的列表):

    previous = None 
    for item in my_list: 
        if previous is None: 
         previous = item 
         continue 
        # do something... 
    
+0

+1選項1可能是最好的imho。 – arshajii

0

不使用itertools可能看起來像一個實用的風格:

for t in zip(mylist, mylist[1:]): 
    compute(*t) 

如果性能就等於您可以通過使用itertools.izip防止拉鍊在intermeida列表的創建。

要覆蓋的特殊情況下,如圖中的問題,使用方法:

for t in zip(mylist, mylist[1:]) + [(mylist[-1],)] 
    compute(*t) 
+0

這爲什麼效率低下? – Bruno

+0

這實際上並不是那麼糟糕,但是zip創建了一個不必要的中間列表。使用[itertools.izip](http://docs.python.org/2/library/itertools。html#itertools.izip),是可取的。 – cmh

1

您可以使用內置的功能enumerate

mylist = [1, 2, 3, 4] 
for i, num in enumerate(mylist): 
    try: 
     compute(num, mylist[i+1]) 
    except IndexError: 
     compute(num) 

但你的兩個實現之間的選擇是相當容易 - 其次不僅要慢得多(O(n^2)),而且對重複元素也有奇怪的語義。

+0

這看起來不錯;感謝您的快速反饋! – Bruno

0

要在年底覆蓋你的特殊情況下,你需要:

for t in zip(mylist, mylist[1:]) + [(mylist[-1],)] 
    compute(*t)