2009-06-10 60 views
3

我有一個項目列表(這是HTML錶行,用美麗的湯提取),我需要迭代列表,並獲得偶數和奇數元素(我的意思是索引)for每個循環運行。 我的代碼如下所示:同時迭代列表的奇偶項

for top, bottom in izip(table[::2], table[1::2]): 
    #do something with top 
    #do something else with bottom 

如何使這個代碼少醜嗎?或者,也許是這樣做的好方法?

編輯:

table[1::2], table[::2] => table[::2], table[1::2] 

回答

4

嘗試:

def alternate(i): 
    i = iter(i) 
    while True: 
     yield(i.next(), i.next()) 

>>> list(alternate(range(10))) 
[(0, 1), (2, 3), (4, 5), (6, 7), (8, 9)] 

該解決方案適用於任何序列,而不僅僅是列出,而不會複製序列(這將是遠,如果更高效你只需要一個長序列的前幾個元素)。

0

看起來不錯。我唯一的建議是將其封裝在一個函數或方法中。這樣,你可以給它一個名字(evenOddIter()),這使得它更具可讀性。

+0

在這種情況下函數和方法有什麼區別? – 2009-06-10 08:11:07

+0

這取決於上面的代碼是否是類或頂級的一部分。如果它在一個被大量重用的類中,那麼使用一個方法可能是有意義的。當使用一個函數時,在任何類外部重複使用會更簡單,但會混淆全局名稱空間。 – 2009-06-10 08:18:28

+0

它在一個類中,但是這個循環只在一個地方執行,所以我認爲有必要從中做出一個方法。無論如何感謝 – uolot 2009-06-10 08:44:38

5

izip是一個不錯的選擇,但在這裏,因爲你不滿意它的幾個備選方案:

>>> def chunker(seq, size): 
...  return (tuple(seq[pos:pos+size]) for pos in xrange(0, len(seq), size)) 
... 
>>> x = range(11) 
>>> x 
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
>>> chunker(x, 2) 
<generator object <genexpr> at 0x00B44328> 
>>> list(chunker(x, 2)) 
[(0, 1), (2, 3), (4, 5), (6, 7), (8, 9), (10,)] 
>>> list(izip(x[1::2], x[::2])) 
[(1, 0), (3, 2), (5, 4), (7, 6), (9, 8)] 

正如你所看到的,這有妥善處理的大小不均的元素,優勢這可能對你不重要。還有這個配方從itertools documentation itself

>>> def grouper(n, iterable, fillvalue=None): 
...  "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx" 
...  args = [iter(iterable)] * n 
...  return izip_longest(fillvalue=fillvalue, *args) 
... 
>>> 
>>> from itertools import izip_longest 
>>> list(grouper(2, x)) 
[(0, 1), (2, 3), (4, 5), (6, 7), (8, 9), (10, None)]