Python round robin list

Round Robin method of mixing of two lists in python

We take each and every tuple and flatten it out with list comprehension.

But as @Ashwini Chaudhary suggested, use roundrobin receipe from the docs

from itertools import cycle from itertools import islice def roundrobin(*iterables): "roundrobin('ABC', 'D', 'EF') --> A D E B F C" # Recipe credited to George Sakkis pending = len(iterables) nexts = cycle(iter(it).next for it in iterables) while pending: try: for next in nexts: yield next() except StopIteration: pending -= 1 nexts = cycle(islice(nexts, pending)) print list(roundrobin(range(5), "hello")) 

You could find a series of iteration recipes here: http://docs.python.org/2.7/library/itertools.html#recipes

from itertools import islice, cycle def roundrobin(*iterables): "roundrobin('ABC', 'D', 'EF') --> A D E B F C" # Recipe credited to George Sakkis pending = len(iterables) nexts = cycle(iter(it).next for it in iterables) while pending: try: for next in nexts: yield next() except StopIteration: pending -= 1 nexts = cycle(islice(nexts, pending)) print list(roundrobin(range(5), "hello")) 

EDIT: Python 3

def roundrobin(*iterables): "roundrobin('ABC', 'D', 'EF') --> A D E B F C" # Recipe credited to George Sakkis num_active = len(iterables) nexts = cycle(iter(it).__next__ for it in iterables) while num_active: try: for next in nexts: yield next() except StopIteration: num_active -= 1 nexts = cycle(islice(nexts, num_active)) print list(roundrobin(range(5), "hello")) 

You can leverage itertools.chain (to unwrap the tuples) with itertools.izip (to transpose the elements in order to create an interleaving pattern) to create your result

>>> from itertools import izip, chain >>> list(chain.from_iterable(izip(range(5), "hello"))) [0, 'h', 1, 'e', 2, 'l', 3, 'l', 4, 'o'] 

If the strings are of unequal length, use izip_longest with a pad value (preferably empty string)

Читайте также:  File type image javascript

Источник

Python list dictionary items round robin mixing

Using python default dict to separate the items by source and then using roundrobin solution which I got from python docs. How can make the solution more pythonic or improved?

2 Answers 2

Using the roundrobin() recipe from itertools is already pythonic. The solve() method could be replaced with more use of itertools .

In particular itertools.groupby() would do the same as your defaultdict and for loop:

>>> import operator as op >>> g, p, t = [list(v) for k, v in groupby(sample, key=op.itemgetter('source'))] >>> list(roundrobin(g, p, t)) [, , , , , , , , , ] 

You don’t really need to unpack as you can make the call to roundrobin() using * , e.g:

>>> x = [list(v) for k, v in it.groupby(sample, key=op.itemgetter('source'))] >>> list(roundrobin(*x)) [, , . 

Note roundrobin() could be rewritten using itertools.zip_longest() , which should be faster for near equal sized iterables e.g.:

def roundrobin(*iterables): sentinel = object() return (a for x in it.zip_longest(*iterables, fillvalue=sentinel) for a in x if a != sentinel) 

Did a quick run of a 10000 random items in sample and found the recipe surprisingly slow (need to figure out why):

In [11]: sample = [ for _ in range(10000)] In [12]: x = [list(v) for k, v in it.groupby(sample, key=op.itemgetter('source'))] In [13]: %timeit list(roundrobin_recipe(*x)) 1 loop, best of 3: 1.48 s per loop In [14]: %timeit list(roundrobin_ziplongest(*x)) 100 loops, best of 3: 4.12 ms per loop In [15]: %timeit TW_zip_longest(*x) 100 loops, best of 3: 6.36 ms per loop In [16]: list(roundrobin_recipe(*x)) == list(roundrobin_ziplongest(*x)) True In [17]: list(roundrobin_recipe(*x)) == TW_zip_longest(*x) True 

Источник

Round Robin method of mixing of two lists in python

We take each and every tuple and flatten it out with list comprehension.

But as @Ashwini Chaudhary suggested, use roundrobin receipe from the docs

from itertools import cycle from itertools import islice def roundrobin(*iterables): "roundrobin('ABC', 'D', 'EF') --> A D E B F C" # Recipe credited to George Sakkis pending = len(iterables) nexts = cycle(iter(it).next for it in iterables) while pending: try: for next in nexts: yield next() except StopIteration: pending -= 1 nexts = cycle(islice(nexts, pending)) print list(roundrobin(range(5), "hello")) 

@AshwiniChaudhary In that case, zip terminates after the first sequence reached it’s end. You can use itertools.zip_longest to pad with None (or any other value).

Читайте также:  Http response class php

@JonasWielicki We don’t pad with None (or any other value) in roundrobin , we need the item from next iterable in that case.

from itertools import islice, cycle def roundrobin(*iterables): "roundrobin('ABC', 'D', 'EF') --> A D E B F C" # Recipe credited to George Sakkis pending = len(iterables) nexts = cycle(iter(it).next for it in iterables) while pending: try: for next in nexts: yield next() except StopIteration: pending -= 1 nexts = cycle(islice(nexts, pending)) print list(roundrobin(range(5), "hello")) 

EDIT: Python 3

def roundrobin(*iterables): "roundrobin('ABC', 'D', 'EF') --> A D E B F C" # Recipe credited to George Sakkis num_active = len(iterables) nexts = cycle(iter(it).__next__ for it in iterables) while num_active: try: for next in nexts: yield next() except StopIteration: num_active -= 1 nexts = cycle(islice(nexts, num_active)) print(list(roundrobin(range(5), "hello"))) 

You can leverage itertools.chain (to unwrap the tuples) with itertools.izip (to transpose the elements in order to create an interleaving pattern) to create your result

>>> from itertools import izip, chain >>> list(chain.from_iterable(izip(range(5), "hello"))) [0, 'h', 1, 'e', 2, 'l', 3, 'l', 4, 'o'] 

If the strings are of unequal length, use izip_longest with a pad value (preferably empty string)

A mixture of the two itertools roundrobin recipes for Python 2 and Python 3 looks like this:

from itertools import islice, cycle def roundrobin(*iterables): "roundrobin('ABC', 'D', 'EF') --> A D E B F C" # Recipe credited to George Sakkis num_active = len(iterables) try: iter([]).__next__ # test attribute nexts = cycle(iter(it).__next__ for it in iterables) except AttributeError: # Python 2 behavior nexts = cycle(iter(it).next for it in iterables) while num_active: try: for next in nexts: yield next() except StopIteration: # Remove the iterator we just exhausted from the cycle. num_active -= 1 nexts = cycle(islice(nexts, num_active)) print(list(roundrobin(range(5), "hello"))) 

Источник

Python list dictionary items round robin mixing

Using python default dict to separate the items by source and then using roundrobin solution which I got from python docs. How can make the solution more pythonic or improved?

Читайте также:  Компилятор для python exe

2 Answers 2

Using the roundrobin() recipe from itertools is already pythonic. The solve() method could be replaced with more use of itertools .

In particular itertools.groupby() would do the same as your defaultdict and for loop:

>>> import operator as op >>> g, p, t = [list(v) for k, v in groupby(sample, key=op.itemgetter('source'))] >>> list(roundrobin(g, p, t)) [, , , , , , , , , ] 

You don’t really need to unpack as you can make the call to roundrobin() using * , e.g:

>>> x = [list(v) for k, v in it.groupby(sample, key=op.itemgetter('source'))] >>> list(roundrobin(*x)) [, , . 

Note roundrobin() could be rewritten using itertools.zip_longest() , which should be faster for near equal sized iterables e.g.:

def roundrobin(*iterables): sentinel = object() return (a for x in it.zip_longest(*iterables, fillvalue=sentinel) for a in x if a != sentinel) 

Did a quick run of a 10000 random items in sample and found the recipe surprisingly slow (need to figure out why):

In [11]: sample = [ for _ in range(10000)] In [12]: x = [list(v) for k, v in it.groupby(sample, key=op.itemgetter('source'))] In [13]: %timeit list(roundrobin_recipe(*x)) 1 loop, best of 3: 1.48 s per loop In [14]: %timeit list(roundrobin_ziplongest(*x)) 100 loops, best of 3: 4.12 ms per loop In [15]: %timeit TW_zip_longest(*x) 100 loops, best of 3: 6.36 ms per loop In [16]: list(roundrobin_recipe(*x)) == list(roundrobin_ziplongest(*x)) True In [17]: list(roundrobin_recipe(*x)) == TW_zip_longest(*x) True 

Источник

Оцените статью