为什么会这样itertools.count计数()与zip一起使用时,是否消耗额外的元素?

2024-04-25 07:32:51 发布

您现在位置:Python中文网/ 问答频道 /正文

我试着用functools.部分与itertools.count计数,通过与itertools.count计数():

g = functools.partial(zip, itertools.count())

当用“abc”、“abc”等输入调用g时,我注意到itertools.count计数()神秘地“跳跃”。你知道吗

我想我应该得到与直接使用zip相同的结果itertools.count计数()? 比如:

>>> x=itertools.count();
>>> list(zip("abc",x))
[('a', 0), ('b', 1), ('c', 2)]
>>> list(zip("ABC",x))
[('A', 3), ('B', 4), ('C', 5)]

但是,我得到了如下结果——注意,第二次调用g时的起始索引是4而不是3:

>>> g = functools.partial(zip, itertools.count())
>>> list(g("abc"))
[(0, 'a'), (1, 'b'), (2, 'c')]
>>> list(g("ABC"))
[(4, 'A'), (5, 'B'), (6, 'C')]

Tags: countzippartiallist计数abcitertoolsfunctools
2条回答

如果将itertools.count()封装在函数中,很容易理解其中的原因:

def count():
    c = itertools.count()
    while True:
        v = next(c)
        print('yielding', v)
        yield v

g = functools.partial(zip, count())
list(g("abc"))

输出为

yielding 0
yielding 1
yielding 2
yielding 3
[(0, 'a'), (1, 'b'), (2, 'c')]

您将看到zip在意识到第二个iteable中没有任何其他内容之前,它将对count()的下一个参数求值(因此产生了一个额外的值3)。你知道吗

作为练习,反转参数,您将看到评估有点不同。你知道吗

请注意,如果您的原始代码以与更改后的代码相同的顺序使用参数,则会得到相同的结果:

>>> x = itertools.count()
>>> list(zip(x, "abc"))
[(0, 'a'), (1, 'b'), (2, 'c')]
>>> list(zip(x, "ABC"))
[(4, 'A'), (5, 'B'), (6, 'C')]

zip()首先尝试它的第一个参数,然后是第二个参数,然后是第三个参数。。。当其中一个筋疲力尽时停止。你知道吗

在上面的拼写中,在"abc"用尽之后,它返回到第一个参数并从x获得3。但是它的第二个参数已经用尽了,所以zip()停止了,而3就悄无声息地丢失了。你知道吗

然后转到第二个zip(),从x获取4。你知道吗

partial()确实与此无关。你知道吗

相关问题 更多 >