Python 在iterables中产生替代值
我得到了许多iterable,我需要生成第一个iterable中的所有值,然后是第二个iterable中的所有值,最后一个iterable中的所有值都是可选的 示例:Python 在iterables中产生替代值,python,python-3.x,Python,Python 3.x,我得到了许多iterable,我需要生成第一个iterable中的所有值,然后是第二个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
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
但是,我该如何生成它们呢?如果您想在最短列表中终止,请使用: 制作一个迭代器,聚合来自每个ITerable的元素 如果要使用所有项目,请使用: 制作一个迭代器,聚合来自每个ITerable的元素。如果iterables的长度不均匀,则缺少的值将用fillvalue填充 请注意,它跳过
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
要在第一个“缺失”项上停止:
如果您正在使用生成器(或迭代器),当其中一个生成器(或迭代器)完成时,您将得到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
这会满足你的要求。它适用于任何输入,如果其中一项为
None
,则不会出错。它使用内置的itertools
模块,并且只使用内置的python模块在Python3.x和Python2.7上工作。它基于Pythonitertools
文档中的函数:
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
什么python版本?@ReutSharabani python 3.
alternate('a','bcdefg','hijkl')
的预期输出是什么?有没有办法不使用izip_longest(*args)?@Hacker688itertools
自Python 2.3以来一直在标准库中。@Hacker688这个问题通过文档链接以及在Python解释器中的一个非常简单的检查(需要5秒钟)得到了回答。@Hacker688 izip_longest在Python 3中被重命名。在python2中,zip_创建的是列表,而不是迭代器。回答中修正了:@Reut Sharabani,但输出是[a f h b g i c j d k e],而不是[a f h b g i c]
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