这是我的出发点。这样就可以了。
l1 = [1, 2, 3, 4]
l2 = [5, 6, 7, 8]
l3 = [9, 10, 11, 12]
def interleave(iterable1, iterable2):
for item1, item2 in zip(iterable1, iterable2):
yield item1
yield item2
print(interleave(l1, l2))
print('-' * 30)
print(list(interleave(l1, l2)))
如果我想将它扩展为使用所有三个列表,我可以这样做:
l1 = [1, 2, 3, 4]
l2 = [5, 6, 7, 8]
l3 = [9, 10, 11, 12]
def interleave(*args):
for item1, item2, item3 in zip(*args):
yield item1
yield item2
yield item3
print(interleave(l1, l2, l3))
print('-' * 30)
print(list(interleave(l1, l2, l3)))
然而,我'解决'使用接收任意数量的输入迭代的问题 * args,但我的项目分配仍然是手动的。
我希望能够说:
def interleave(*args):
for *items in zip(*args):
yield items
允许我将任意数量的输入变量解压缩到*项目中,但是我收到此错误:
SyntaxError: starred assignment target must be in a list or tuple
我不想说*items = <something>
。我希望*项目可以接收任意数量的输入变量。
如果我有六个列表,我不想说item1,item2,...,item6,后跟相同数量的收益。
这真的不是很容易扩展。
有办法做我想做的事吗?
答案 0 :(得分:2)
对于3.3之前的Python,使用嵌套的for循环。
def interleave(*args):
for items in zip(*args):
for item in items:
yield item
对于Python 3.3+,您可以将yield from
用于generator delegation,这是上面的语法糖。
def interleave(*args):
for items in zip(*args):
yield from items
或者最后,如果您需要一个允许不同长度列表的更通用的解决方案,请使用itertools recipes中的roundrobin
函数。
def roundrobin(*iterables):
"roundrobin('ABC', 'D', 'EF') --> A D E B F C"
# Recipe credited to George Sakkis
num_active = len(iterables)
nexts = cycle(iter(it).__next__ for it in iterables)
while num_active:
try:
for next in nexts:
yield next()
except StopIteration:
# Remove the iterator we just exhausted from the cycle.
num_active -= 1
nexts = cycle(islice(nexts, num_active))
答案 1 :(得分:0)
嵌套循环?
def interleave(*args):
for items in zip(*args):
for item in items:
yield items