我得到了许多迭代,我需要在第一个iterable中生成所有值,然后在第二个中生成所有值,...,最后一个iterable中的所有值。
示例:
for i in alternate('abcde','fg','hijk'):
print(i,end=' ')
预计会产生值
a f h b g i c
我知道按顺序打印所有字符,如
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'
以下是代码:
def alternate(*args):
for iterable in args:
for item in iterable:
yield item
但是如何让它们交替出现呢?
答案 0 :(得分:5)
如果您想在最短列表中终止,请使用zip
:
创建一个聚合来自每个迭代的元素的迭代器。
def alternate(*args):
# note: python 2 - use izip_longest
for iterable in zip(*args):
for item in iterable:
if item is not None:
yield item
如果您想使用所有项目,请使用itertools.izip_longest:
创建一个聚合来自每个迭代的元素的迭代器。如果迭代的长度不均匀,则使用fillvalue填充缺失值。
def alternate(*args):
# note: python 2 - use izip_longest
for iterable in itertools.zip_longest(*args):
for item in iterable:
if item is not None:
yield item
请注意,它会跳过None
个值(可以使用fillvalue
更改)。
没有itertools
:
def alternate(*args):
max_len = max(map(len, args))
for index in range(max_len):
for lst in args:
try:
yield lst[index]
except IndexError:
continue
停止第一个“缺失”项目:
def alternate(*args):
index = 0
while True:
for lst in args:
try:
yield lst[index]
except IndexError:
return
index += 1
如果您正在使用生成器(或迭代器),当其中一个完成时,您将获得StopIteration
,因此您可以使用iter
创建一般函数:
def alternate(*args):
iters = [iter(lst) for lst in args]
while True:
for itr in iters:
try:
yield next(itr)
except StopIteration:
return
答案 1 :(得分:0)
这将做你想要的。它适用于任何输入,如果其中一个项目为None
,则不会绊倒。它使用内置的itertools
模块,只能使用内置的python模块在python 3.x和python 2.7上运行。它基于Python itertools
文档中的roundrobin
函数:
from itertools import cycle
def roundrobin_shortest(*iterables):
"roundrobin_shortest('ABCD', 'EF', 'GHI') --> A E G B F H C"
nexts = cycle(iter(it).__next__ for it in iterables)
while True:
try:
for inext in nexts:
yield inext()
except StopIteration:
break
此版本的工作原理基本相同,但有点短:
from itertools import chain, cycle
def roundrobin_shortest(*iterables):
"roundrobin_shortest('ABCD', 'EF', 'GHI') --> A E G B F H C"
nexts = cycle(iter(it).__next__ for it in iterables)
yield from chain.from_iterable(inext() for inext in nexts)
没有itertools的版本:
def roundrobin_shortest(*iterables):
"roundrobin_shortest('ABCD', 'EF', 'GHI') --> A E G B F H C"
items = [iter(item) for item in iterables]
while True:
try:
for it in items:
yield next(it)
except StopIteration:
break
你可以使用以下任何一种:
>>> for i in roundrobin_shortest('abcde','fg','hijk'):
... print(i, end=' ')
...
a f h b g i c
或者这是一个更简单的单行
>>> from itertools import chain, cycle
>>> iters = ('abcde','fg','hijk')
>>> res = chain.from_iterable(j() for j in cycle(iter(j).__next__ for j in iters))
>>> print(' '.join(res))
a f h b g i c