如何解决Python zip():检查哪个迭代已耗尽
在 Python 3 中,zip(*iterables)
自 documentation
返回一个元组迭代器,其中第 i 个元组包含来自每个参数序列或可迭代对象的第 i 个元素。当最短的输入迭代用完时,迭代器停止。
举个例子,我正在跑步
for x in zip(a,b):
f(x)
有没有办法找出哪些可迭代对象 a
或 b
导致 zip 迭代器停止?
假设 len()
不可靠并且迭代 a
和 b
以检查它们的长度是不可行的。
解决方法
我认为简给出了最好的答案。基本上,您希望单独处理 zip 中的最后一次迭代。
import itertools as it
a = (x for x in range(5))
b = (x for x in range(3))
iterables = ((it.chain(g,[f"generator {i} was exhausted"]) for i,g in enumerate([a,b])))
for i,j in zip(*iterables):
print(i,j)
# 0 0
# 1 1
# 2 2
# 3 generator 1 was exhausted
,
如果你只有两个可迭代对象,你可以使用下面的代码。 The exhausted[0]
将拥有迭代器耗尽的指标。 None 的值表示两者都已耗尽。
但是我必须说我不同意 len()
不可靠。事实上,您应该依靠 len()
调用来确定答案。 (除非你告诉我们你不能的原因。)
def f(val):
print(val)
def manual_iter(a,b,exhausted):
iters = [iter(it) for it in [a,b]]
iter_map = {}
iter_map[iters[0]] = 'first'
iter_map[iters[1]] = 'second'
while 1:
values = []
for i,it in enumerate(iters):
try:
value = next(it)
except StopIteration:
if i == 0:
try:
next(iters[1])
except StopIteration:
return None
exhausted.append(iter_map[it])
return iter_map[it]
values.append(value)
yield tuple(values)
if __name__ == '__main__':
exhausted = []
a = [1,2,3]
b = [10,20,30]
for x in manual_iter(a,exhausted):
f(x)
print(exhausted)
exhausted = []
a = [1,3,4]
b = [10,30,40]
for x in manual_iter(a,exhausted):
f(x)
print(exhausted)
,
我找到了以下解决方案,该解决方案将 zip
替换为 for
循环,仅覆盖第一个可迭代对象,并在循环内迭代第二个。
ib = iter(b)
for r in a:
try:
s = next(ib)
except StopIteration:
print('Only b exhausted.')
break
print((r,s))
else:
try:
s = next(ib)
print('Only a exhausted.')
except StopIteration:
print('a and b exhausted.')
这里 ib = iter(b)
确保它在 b
是序列或生成器对象时也能工作。 print((r,s))
将替换为问题中的 f(x)
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。