Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

generate tuple of values from iterables in Python 3

If a function gets passed an undefined number of iterables N of arbitrary length M, is there a way to obtain a generator that yield M tuples of size N containing the elements of the passed iterables?

def dispatch(*iterables):
    args = ( some kind of generator that involves *iterables)
    for _ in args:
        yield _

In other words, if we consider *iterables as an NxM matrix in which each column (function argument) is an iterable is there a way using a generator to yield the rows of the matrix?

Eg:

a = [9,8,7,6]
b = 'ciao'
c = iter(range(0,4))

>>> res = dispatch(a,b,c)
>>> res.__next__()
(9,c,0)
>>> res.__next__()
(8,i,1)

etc...

furthermore since this function could also take only 1 iterable as argument, the generator should be able to handle the case and output something like:

a = [9,8,7,6]
>>> res = dispatch(a)
>>> res.__next__()
(9,)
>>> res.__next__()
(8,)

I tried using zip but it doesn't handle the aforementioned edge case, plus it is kind of slow, which suggest that it probably has to read the whole thing before producing an output.

like image 331
darkpirate Avatar asked Mar 14 '26 04:03

darkpirate


1 Answers

You can use map combined with a lambda that pack the arguments:

>>> list(map(lambda *x: tuple(x), range(10), range(10), range(10)))
[(0, 0, 0), (1, 1, 1), (2, 2, 2), (3, 3, 3), (4, 4, 4), (5, 5, 5), (6, 6, 6), (7, 7, 7), (8, 8, 8), (9, 9, 9)]
>>> list(map(lambda *x: tuple(x), range(10)))
[(0,), (1,), (2,), (3,), (4,), (5,), (6,), (7,), (8,), (9,)]

Your function would be really simple:

def dispatch(*args):
    return map(lambda *x: tuple(x), *args)

As in your example:

>>> a = [9,8,7,6]
>>> b = 'ciao'
>>> c = iter(range(0,4))
>>> list(dispatch(a, b, c))
[(9, 'c', 0), (8, 'i', 1), (7, 'a', 2), (6, 'o', 3)]
like image 139
Netwave Avatar answered Mar 15 '26 16:03

Netwave



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!