没有填充值的 zip_longest [英] zip_longest without fillvalue
问题描述
我正在寻找 Python 的 zip
和 zip_longest
函数(来自 itertools 模块)之间的中间地带,它耗尽了所有给定的迭代器,但不填写任何内容.因此,例如,它应该像这样转置元组:
I am searching for a middle ground between Python's zip
and zip_longest
functions (from the itertools module), that exhausts all given iterators, but does not fill in anything. So, for example, it should transpose tuples like so:
(11, 12, 13 ), (11, 21, 31, 41),
(21, 22, 23, 24), --> (12, 22, 32, 42),
(31, 32 ), (13, 23, 43),
(41, 42, 43, 44), ( 24, 44)
(为了更好的图形对齐添加了空格.)
我设法通过清除 zip_longest
之后的 fillvalue
来编写一个粗略的解决方案.
I managed to compose a crude a solution by cleaning out the fillvalue
s after zip_longest
.
def zip_discard(*iterables, sentinel = object()):
return map(
partial(filter, partial(is_not, sentinel)),
zip_longest(*iterables, fillvalue=sentinel))
有没有办法在不引入哨兵的情况下做到这一点?这可以使用 yield
改进吗?哪种方法看起来最有效?
Is there a way to do this without introducing the sentinels to begin with? Can this be improved using yield
? Which approach seems most efficient?
推荐答案
zip
和 zip_longest
都被设计为总是生成等长的元组,你可以定义自己的不关心 len 的生成器,如下所示:
Both zip
and zip_longest
were designed to always generate tuples of equal length, you can define your own generator that doesn't care about the len with something like this:
def _one_pass(iters):
for it in iters:
try:
yield next(it)
except StopIteration:
pass #of some of them are already exhausted then ignore it.
def zip_varlen(*iterables):
iters = [iter(it) for it in iterables]
while True: #broken when an empty tuple is given by _one_pass
val = tuple(_one_pass(iters))
if val:
yield val
else:
break
如果压缩在一起的数据相当大,那么每次跳过耗尽的迭代器可能会很昂贵,从 _one_pass
中的 iters
中删除完成的迭代器可能更有效代码>函数如下:
If the data being zipped together is fairly large then skipping the exhausted iterators every time can be expensive, it may be more efficient to remove the finished iterators from iters
in the _one_pass
function like this:
def _one_pass(iters):
i = 0
while i<len(iters):
try:
yield next(iters[i])
except StopIteration:
del iters[i]
else:
i+=1
这两个版本都不需要创建中间结果或使用临时填充值.
both of these versions would remove the need to create intermediate results or use temporary filler values.
这篇关于没有填充值的 zip_longest的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!