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

发布于 2024-07-24 04:11:34 字数 371 浏览 10 评论 0原文

我有一个项目列表(它们是 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]

I have a list of items (which are HTML table rows, extracted with Beautiful Soup) and I need to iterate over the list and get even and odd elements (I mean index) for each loop run.
My code looks like this:

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

How to make this code less ugly? Or maybe is it good way to do this?

EDIT:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

酒中人 2024-07-31 04:11:34

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

izip is a pretty good option, but here's a few alternatives since you're unhappy with it:

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

As you can see, this has the advantage of properly handling an uneven amount of elements, which may or not be important to you. There's also this recipe from the 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)]
把梦留给海 2024-07-31 04:11:34

尝试:

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

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

Try:

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

This solution works on any sequence, not just lists, and doesn't copy the sequence (it will be far more efficient if you only want the first few elements of a long sequence).

九厘米的零° 2024-07-31 04:11:34

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

Looks good. My only suggestion would be to wrap this in a function or method. That way, you can give it a name (evenOddIter()) which makes it much more readable.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文