同时迭代列表中偶数和奇数项

4 投票
3 回答
3782 浏览
提问于 2025-04-15 12:09

我有一个项目列表(这些项目是用Beautiful Soup提取的HTML表格行),我需要遍历这个列表,并在每次循环中获取偶数和奇数的元素(我指的是索引)。

我的代码是这样的:

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]

3 个回答

0

看起来不错。我唯一的建议是把这个放在一个函数或者方法里。这样你可以给它起个名字(比如 evenOddIter()),这样会让代码更容易理解。

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)]
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)]

这个方法适用于任何类型的序列,不仅仅是列表,而且它不会复制整个序列(如果你只想要长序列中的前几个元素,这样会更有效率)。

撰写回答