Одновременное повторение четных и нечетных элементов списка - PullRequest
4 голосов
/ 10 июня 2009

У меня есть список элементов (которые представляют собой строки таблицы 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]

Ответы [ 3 ]

5 голосов
/ 10 июня 2009

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 голосов
/ 10 июня 2009

Попробуйте:

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

Это решение работает с любой последовательностью, а не только со списками, и не копирует последовательность (оно будет гораздо более эффективным, если вы захотите только первые несколько элементов длинной последовательности).

0 голосов
/ 10 июня 2009

выглядит хорошо. Мое единственное предложение - заключить это в функцию или метод. Таким образом, вы можете дать ему имя (evenOddIter()), что сделает его более читабельным.

...