【问题标题】:concurrently iterating through even and odd items of list同时迭代列表的偶数和奇数项
【发布时间】:2010-11-01 17:35:25
【问题描述】:

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

【问题讨论】:

    标签: python for-loop itertools


    【解决方案1】:

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

    【讨论】:

    • 谢谢 - 两个食谱看起来都不错。无论如何,我问是因为我感兴趣还有其他方法可以做到这一点(并学习更多 Python ——我做到了:))
    【解决方案2】:

    试试:

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

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 在这种情况下,函数和方法有什么区别?
      • 这取决于上面的代码是类的一部分还是顶层的。如果它在一个得到大量重用的类中,那么使用一个方法可能是有意义的。使用函数时,在任何类之外重用会更简单,但会使全局命名空间变得混乱。
      • 它在一个类中,但是这个循环只在一个地方执行,所以我认为有必要从中创建一个方法。还是谢谢
      猜你喜欢
      • 2017-02-06
      • 2022-12-01
      • 2011-12-18
      • 1970-01-01
      • 2020-10-28
      • 2016-04-12
      • 2012-06-06
      • 1970-01-01
      • 2017-01-04
      相关资源
      最近更新 更多