Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to split an iterable into two lists with alternating elements

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'])
like image 627
Sridhar Ratnakumar Avatar asked Sep 18 '09 05:09

Sridhar Ratnakumar


People also ask

Which operation refers to separating the elements of one list into two or more lists?

Write a function AlternatingSplit() that takes one list and divides up its nodes to make two smaller lists 'a' and 'b'. The sublists should be made from alternating elements in the original list.

How do you split lists by condition?

split() , to split the list into an ordered collection of consecutive sub-lists. E.g. split([1,2,3,4,5,3,6], 3) -> ([1,2],[4,5],[6]) , as opposed to dividing a list's elements by category. Discussion of the same topic on python-list.


2 Answers

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

like image 44
Rafał Dowgird Avatar answered Sep 29 '22 13:09

Rafał Dowgird


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
like image 135
Alex Martelli Avatar answered Sep 29 '22 11:09

Alex Martelli