18

I want to split an iterable into two lists with alternating elements. Here is a working solution. But is there a simpler way to achieve the same?

def zigzag(seq):
    """Return two sequences with alternating elements from `seq`"""
    x, y = [], []
    p, q = x, y
    for e in seq:
        p.append(e)
        p, q = q, p
    return x, y

Sample output:

>>> zigzag('123456')
(['1', '3', '5'], ['2', '4', '6'])
Georgy
  • 12,464
  • 7
  • 65
  • 73
Sridhar Ratnakumar
  • 81,433
  • 63
  • 146
  • 187

4 Answers4

50

If seq is a sequence, then:

def zigzag(seq):
  return seq[::2], seq[1::2]

If seq is a totally generic iterable, such as possibly a generator:

def zigzag(seq):
  results = [], []
  for i, e in enumerate(seq):
    results[i%2].append(e)
  return results
Georgy
  • 12,464
  • 7
  • 65
  • 73
Alex Martelli
  • 854,459
  • 170
  • 1,222
  • 1,395
  • 2
    @Sridhar, don't think of it as lazy, think of it as *time-efficient*. I spent half an hour working working on an algorithm to do this with a *for* loop (for *x* columns, not just two). And although I got it working, it just didn't seem *pythonic* - I suspected there was an easier way. Sure enough, I didn't remember that lists have *step* variables (as shown in this Answer), which makes it trivial. – John C May 08 '11 at 15:37
11

This takes an iterator and returns two iterators:

import itertools
def zigzag(seq):
    t1,t2 = itertools.tee(seq)
    even = itertools.islice(t1,0,None,2)
    odd = itertools.islice(t2,1,None,2)
    return even,odd

If you prefer lists then you can return list(even),list(odd).

Sнаđошƒаӽ
  • 16,753
  • 12
  • 73
  • 90
Rafał Dowgird
  • 43,216
  • 11
  • 77
  • 90
9
def zigzag(seq):
    return seq[::2], seq[1::2]
cobbal
  • 69,903
  • 20
  • 143
  • 156
0

I just wanted to clear something. Say you have a list

list1 = list(range(200))

you can do either :

## OPTION A ##
a = list1[1::2]
b = list1[0::2]

or

## OPTION B ##
a = list1[0:][::2] # even
b = list1[1:][::2] # odd

And get have alternative elements in variable a and b.

But OPTION A is twice as fast

bad programmer
  • 818
  • 7
  • 12