从 Python 中的可迭代对象生成值的元组 3
generate tuple of values from iterables in Python 3
如果一个函数传递了一个未定义数量的任意长度 M 的迭代器 N,有没有办法获得一个生成器,该生成器产生 M 个大小为 N 的元组,其中包含传递的迭代器的元素?
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 个可迭代对象作为参数,因此生成器应该能够处理这种情况并输出
类似于:
a = [9,8,7,6]
>>> res = dispatch(a)
>>> res.__next__()
(9,)
>>> res.__next__()
(8,)
我尝试使用 zip,但它不能处理上述边缘情况,而且它有点慢,这表明它可能必须在生成输出之前读取整个内容。
使用 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,)
您可以将 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)]
如果一个函数传递了一个未定义数量的任意长度 M 的迭代器 N,有没有办法获得一个生成器,该生成器产生 M 个大小为 N 的元组,其中包含传递的迭代器的元素?
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 个可迭代对象作为参数,因此生成器应该能够处理这种情况并输出 类似于:
a = [9,8,7,6]
>>> res = dispatch(a)
>>> res.__next__()
(9,)
>>> res.__next__()
(8,)
我尝试使用 zip,但它不能处理上述边缘情况,而且它有点慢,这表明它可能必须在生成输出之前读取整个内容。
使用 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,)
您可以将 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)]