15

文档说笛卡尔积函数

the actual implementation does not build up intermediate results in memory.

发电机怎么可能做到这一点?有人可以向我展示一个 2 个生成器的内存消耗有限的示例吗?

4

2 回答 2

12

查看模块的源代码,itertools.product()实际上将每个参数转换为一个元组:

// product_new() in itertoolsmodule.c
for (i=0; i < nargs ; ++i) {
    PyObject *item = PyTuple_GET_ITEM(args, i);
    PyObject *pool = PySequence_Tuple(item); //<==== Call tuple(arg)
    if (pool == NULL)
        goto error;
    PyTuple_SET_ITEM(pools, i, pool);
    indices[i] = 0;
}

换句话说,itertools.product()的内存消耗似乎与输入参数的大小呈线性关系。

于 2012-05-23T12:57:20.973 回答
4

好吧,它还说:

嵌套循环像里程表一样循环,每次迭代时最右边的元素都会前进。此模式创建一个字典顺序,以便如果输入的可迭代项已排序,则产品元组按排序顺序发出。

这几乎就是它在实现中的工作方式(Modules/itertoolsmodule.c

这是状态对象:

typedef struct {
    PyObject_HEAD
    PyObject *pools;       /* tuple of pool tuples */
    Py_ssize_t *indices;   /* one index per pool */
    PyObject *result;      /* most recently returned result tuple */
    int stopped;           /* set to 1 when the product iterator is exhausted */
} productobject;

下一项由函数返回,该函数product_next使用此状态和引用中描述的算法来生成下一个状态。请参阅此答案以了解内存要求。

对于普通教育,您可以在此处阅读有关如何从 C 扩展中创建具有状态的生成器的信息。

于 2012-05-23T12:56:11.523 回答