当前位置: 首页 > 面试题库 >

Python迭代器的怪异行为

松骏俊
2023-03-14
问题内容

这个问题已经在这里有了答案

嵌套函数中的局部变量 (4个答案)

5年前关闭。

我在玩Python生成器和itertools模块,并尝试制作无限版的Eratosthenes筛。这是我的代码:

from itertools import count, ifilter, islice

def sieve_broken():
    candidates = count(start=2)
    while True:
        prime = next(candidates)
        yield prime
        candidates = ifilter(lambda n: n % prime, candidates)

当我对其进行测试时,我得到以下信息:

>>> print list(islice(sieve_broken(), 10))
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

但是,如果我用candidates这样的函数代替的重新分配:

def sieve_fixed():
    def exclude_multiples(factor, numbers):
        return ifilter(lambda n: n % factor, numbers)

    candidates = count(start=2)
    while True:
        prime = next(candidates)
        yield prime
        candidates = exclude_multiples(prime, candidates)

我得到:

>>> print list(islice(sieve_fixed(), 10))
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]

我不知道为什么第一个版本不起作用。据我所知,这两个版本应该等效。有谁知道为什么他们不一样?


问题答案:

在Python中使用闭包时,您已经陷入了一个非常普遍的陷阱:闭包具有其作用域,并且您会在同一范围内继续替换值。

candidates = ifilter(lambda n, prime=prime: n % prime, candidates)


 类似资料:
  • 前面章节中,已经对列表(list)、元组(tuple)、字典(dict)、集合(set)这些序列式容器做了详细的介绍。值得一提的是,这些序列式容器有一个共同的特性,它们都支持使用 for 循环遍历存储的元素,都是可迭代的,因此它们又有一个别称,即迭代器。 从字面来理解,迭代器指的就是支持迭代的容器,更确切的说,是支持迭代的容器类对象,这里的容器可以是列表、元组等这些 Python 提供的基础容器,

  • 上面简单的介绍了一下迭代,迭代是 Python 最强大的功能之一,是访问集合元素的一种方式。现在正式进入主题:迭代器,迭代器是一个可以记住遍历的位置的对象。 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。 迭代器只能往前不会后退。 迭代器有两个基本的方法:iter() 和 next(),且字符串,列表或元组对象都可用于创建迭代器,迭代器对象可以使用常规 for 语句进行遍历,也

  • 我创建了两个长列表,重复两个不同的值。在第一个列表中,值交替出现,在第二个列表中,一个值出现在另一个值之前: 然后我迭代它们,对它们不做任何操作: 两者哪个迭代更快?取决于我如何测量!我用每种计时方法跑了50场比赛: 为什么这两种计时方法给我的结果完全相反?为什么这两个列表之间存在速度差异?我希望有两次25-25,而不是50-0和0-50。 之前类似问题的原因以及我认为他们不应该对此负责的原因:

  • 问题内容: 我想了解更多有关的信息,所以如果我错了,请纠正我。 迭代器是一个对象,该对象具有指向下一个对象的指针,并作为缓冲区或流(即,链表)读取。它们特别有效,因为它们所做的只是通过引用而不是使用索引来告诉您下一步是什么。 但是我仍然不明白为什么会发生以下行为: 经过迭代器()的第一个循环后,就好像它已被消耗并且留空,因此第二个循环()不输出任何内容。 但是,我从未为变量分配新值。 循环幕后到底

  • JavaScript中有没有已知的技巧来区分和之间的区别,而不触发迭代? 我正在尝试实现以下类型检查器: 我知道调用会告诉我们这一点,但在无法触发迭代时我需要它。 此外,即使我在TypeScript中给出了示例,我也需要在运行时严格检查它。

  • 本文向大家介绍Python迭代器与可迭代与生成器,包括了Python迭代器与可迭代与生成器的使用技巧和注意事项,需要的朋友参考一下 示例 一个迭代是一个对象,可以返回一个迭代器。具有状态且具有__iter__  方法并返回迭代器的任何对象都是可迭代的。也可能是没有状态的对象,该对象实现了__getitem__方法。-该方法可以获取索引(从零开始),并IndexError在索引不再有效时引发。 Py