压缩的Python生成器,第二个更短:如何检索静默使用的元素 [英] Zipped Python generators with 2nd one being shorter: how to retrieve element that is silently consumed

查看:22
本文介绍了压缩的Python生成器,第二个更短:如何检索静默使用的元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用zip解析两个(可能)不同长度的生成器:

for el1, el2 in zip(gen1, gen2):
    print(el1, el2)

但是,如果gen2的元素较少,则gen1中的一个额外元素将被"消耗"。

例如

def my_gen(n:int):
    for i in range(n):
        yield i

gen1 = my_gen(10)
gen2 = my_gen(8)

list(zip(gen1, gen2))  # Last tuple is (7, 7)
print(next(gen1))  # printed value is "9" => 8 is missing

gen1 = my_gen(8)
gen2 = my_gen(10)

list(zip(gen1, gen2))  # Last tuple is (7, 7)
print(next(gen2))  # printed value is "8" => OK
显然,缺少一个值(在我的上一个示例中为8),因为gen1在它意识到gen2没有更多元素之前被读取(从而生成值8)。但这个价值在宇宙中消失了。当gen2为"较长"时,不存在此类"问题"。

问题:有没有办法检索这个缺失值(即我上一个示例中的8)?...理想情况下使用可变数量的参数(如zip)。

注意我目前使用itertools.zip_longest以另一种方式实现,但我真的很想知道如何使用zip或等效项获取此缺少的值。

注2我已经为此REPL中的不同实现创建了一些测试,以防您提交并尝试新的实现:)https://repl.it/@jfthuong/MadPhysicistChester

推荐答案

如果您想要重用代码,最简单的解决方案是:

from more_itertools import peekable

a = peekable(a)
b = peekable(b)

while True:
    try:
        a.peek()
        b.peek()
    except StopIteration:
        break
    x = next(a)
    y = next(b)
    print(x, y)


print(list(a), list(b))  # Misses nothing.

您可以使用您的设置测试此代码:

def my_gen(n: int):
    yield from range(n)

a = my_gen(10)
b = my_gen(8)

将打印:

0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
[8, 9] []

这篇关于压缩的Python生成器,第二个更短:如何检索静默使用的元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆