在Python 3中从可迭代项生成值的元组

时间:2019-05-24 12:13:44

标签: python python-3.x iterable-unpacking

如果一个函数被传递了任意长度M的未定义数量的可迭代数N,是否有办法获得一个生成大小为N的M个元组的生成器,其中包含所传递的可迭代的元素?

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

换句话说,如果我们将* iterables视为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个iterable作为参数,因此生成器应该能够处理大小写并输出 像这样:

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

我尝试使用zip,但它不能处理上述边缘情况,而且速度较慢,这表明它可能必须在产生输出之前先读取整个内容。

2 个答案:

答案 0 :(得分:3)

您可以将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)]

答案 1 :(得分:2)

使用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,)