4

我有一个项目列表(它们是 HTML 表格行,用 Beautiful Soup 提取),我需要遍历列表并为每个循环运行获取偶数和奇数元素(我的意思是索引)。我的代码如下所示:

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

3 回答 3

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 文档本身也有这个配方:

>>> 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)]
于 2009-06-10T08:04:56.877 回答
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)]

此解决方案适用于任何序列,而不仅仅是列表,并且不复制序列(如果您只想要长序列的前几个元素,它将更加有效)。

于 2009-06-10T09:33:42.033 回答
0

看起来不错。我唯一的建议是将它包装在一个函数或方法中。这样,您可以给它起一个名称 ( evenOddIter()),使其更具可读性。

于 2009-06-10T08:04:39.063 回答