简体   繁体   English

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

[英]concurrently iterating through even and odd items of list

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. 我有一个项目列表(HTML表格行,用Beautiful Soup提取),我需要遍历列表并获得每个循环运行的偶数和奇数元素(我的意思是索引)。 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]

izip is a pretty good option, but here's a few alternatives since you're unhappy with it: 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)]

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 : 还有来自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)]

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). 此解决方案适用于任何序列,而不仅仅是列表,并且不会复制序列(如果您只想要长序列的前几个元素,它将更有效)。

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. 这样,你可以给它一个名字( evenOddIter() ),这使它更具可读性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM