генерировать кортеж значений из итераций в Python 3 - PullRequest
3 голосов
/ 24 мая 2019

Если функции передается неопределенное количество итераций N произвольной длины M, есть ли способ получить генератор, который выдает M наборов размера N, содержащих элементы пропущенных итераций?

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

Другими словами, если мы рассмотрим * итерируемые как матрицу NxM, в которой каждый столбец (аргумент функции) является итеративным, есть ли способ использовать генератор для получения строк матрицы?

Например:

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

Более того, поскольку эта функция также может принимать только 1 итерацию в качестве аргумента, генератор должен иметь возможность обрабатывать регистр и выводить что-то вроде:

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

Я пытался использовать zip, но это нене обрабатывает вышеупомянутый крайний случай, плюс он довольно медленный, что говорит о том, что он, вероятно, должен прочитать все перед тем, как произвести вывод.

Ответы [ 2 ]

3 голосов
/ 24 мая 2019

Вы можете использовать map в сочетании с lambda, который упаковывает аргументы:

>>> 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,)]

Ваша функция будет очень простой:

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

Как в вашем примере:

>>> 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)]
2 голосов
/ 24 мая 2019

Используйте zip() с распаковкой:

def dispatch(*iterables):
    args = zip(*iterables)
    for _ in args:
        yield _

, что дает:

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)

и для одного аргумента:

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