range是一个惰性序列,但在Python中不是生成器吗?

问题描述 投票:1回答:1

我听说范围是一个生成器,后来我意识到它不是通过this helpful post。尽管这篇文章彻底解释了__contains__方法在恒定时间内的工作方式,但我无法找到有关如何创建惰性序列的任何源代码参考。我试图自己破译source code,但由于我只掌握C的基本知识,所以我很努力。我相信下面的代码段是__iter__在范围内的工作方式(如果我错了,请纠正我)-您能否阐明此处的延迟序列实现方式?它与生成器的延迟序列有什么不同吗?

range_iter(PyObject *seq)
{
    rangeobject *r = (rangeobject *)seq;
    longrangeiterobject *it;
    long lstart, lstop, lstep;
    PyObject *int_it;

  long_range:
    it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type);
    if (it == NULL)
        return NULL;


    it->start = r->start;
    it->step = r->step;
    it->len = r->length;
    it->index = _PyLong_Zero;
    Py_INCREF(it->start);
    Py_INCREF(it->step);
    Py_INCREF(it->len);
    Py_INCREF(it->index);
    return (PyObject *)it;
}
python range generator cpython lazy-sequences
1个回答
0
投票

因此range对象基本上只是数字startstopstep(称为“跨步”)。您必须了解的关键思想是,检查数字是否在由开始,停止和逐步定义的算术序列中,这相当于执行简单的算术运算,这就是为什么O(1)。

如果您实际上看的是源代码,则由于逻辑已包含在注释中,因此您不必很好地理解C,因此,当您执行x in range(start, stop, step)时>

https://github.com/python/cpython/blob/f3a0a6bbccfcd9d18afe5575617aefaee9fa37a5/Objects/rangeobject.c#L353

因此,对于所有正数的简单情况,阅读注释揭示了:

/* Check if the value can possibly be in the range. */
...
/* positive steps: start <= ob < stop */
...
/* Check that the stride does not invalidate ob's membership. */
...
/* result = ((int(ob) - start) % step) == 0 */
© www.soinside.com 2019 - 2024. All rights reserved.