Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

izip_longest with looping instead of fillvalue

Tags:

python

Not sure how to look around for this, but from itertools the function izip_longest does this:

izip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D-

I was hoping an iterable library would have something to do this:

izip_longest_better('ABCDE', 'xy') --> Ax By Cx Dy Ex

Preferably for an arbitrary number of iterables, being used to generate millions of combinations. I'll write my own, but I figured I'd ask, since I'm sure my own won't be very pythonic.

Awesome, It was the cycle that I hadn't tried. I was also able to get something working by nesting for loops on arrays instead of iterators, but this is much better. What I finally used was this to handle similar to izip"

EDIT: Ended up with

def izip_longest_repeat(*args):
    if args:
        lists = sorted(args, key=len, reverse=True)
        result = list(itertools.izip(*([lists[0]] + [itertools.cycle(l) for l in lists[1:]])))
    else:
        result = [()]
    return result
like image 360
adzuci Avatar asked Mar 03 '12 00:03

adzuci


2 Answers

Something like this?

>>> import itertools
>>> 
>>> a = 'ABCDE'
>>> b = 'xy'
>>> 
>>> list(itertools.izip_longest(a, b, fillvalue='-'))
[('A', 'x'), ('B', 'y'), ('C', '-'), ('D', '-'), ('E', '-')]
>>> list(itertools.izip(a, itertools.cycle(b)))
[('A', 'x'), ('B', 'y'), ('C', 'x'), ('D', 'y'), ('E', 'x')]

etc. And there's the arbitrary-number-of-iterables variant (assuming that you don't want the first argument to cycle, and that you're not really interested in itertools.product):

>>> a = 'ABCDE'
>>> bs = ['xy', (1,2,3), ['apple']]
>>> it = itertools.izip(*([a] + [itertools.cycle(b) for b in bs]))
>>> list(it)
[('A', 'x', 1, 'apple'), ('B', 'y', 2, 'apple'), ('C', 'x', 3, 'apple'), 
('D', 'y', 1, 'apple'), ('E', 'x', 2, 'apple')]
like image 91
DSM Avatar answered Sep 22 '22 19:09

DSM


For Python 3 you want to use zip_longest As izip_longest has been deprecated.

import itertools
list = list(itertools.zip_longest('ABCD', 'xy', fillvalue='-'))
print(list) // --> Ax By C- D-
like image 29
Developer Avatar answered Sep 19 '22 19:09

Developer