Skip to content

[BUG] Creating fixed size list by multiplication is not optimised #3922

Description

@jakirkham

It would be useful to have an efficient way to construct a fixed sized list using Python-like code in Cython.

Is your feature request related to a problem? Please describe.

For example, one might have the following code in Python...

def new_list(n: "Py_ssize_t") -> list:
    l: list = n * [None]
    return l

Though once this is compiled, it appears to coerce n to a Python int, create a singleton list with None, and use Number based multiplication between n and the singleton list. Preferably this would allocate a list of size n and then fill it with None in a C for-loop.

Describe the solution you'd like

Instead of generating code that relies on append or handling things at the Python level, it would be helpful to have some code roughly like this (error handling and refcounting skipped for simplicity).

{
    PyObject* l = PyList_New(n);
    Py_ssize_t i;
    for (i = 0; i < n; i++) {
        PyList_SET_ITEM(l, i, Py_None);
    }
    // ...
]

Describe alternatives you've considered

One could try to use generators, though they don't look at the size hint as noted in issue ( #1311 ) and issue ( #2844 ). Plus these wind up being less performant than this implementation is in pure Python. Though Cython performance is likely fine with the other approach. Perhaps if Cython reinterpreted n * [None] as [None for i in n], this could benefit from whatever solution is determined for the generator issues noted before.

Additional context

This comes up periodically when one wants to quickly preallocate a fixed sized Python list and some other alternative like an array wouldn't otherwise work (for example needing to hold arbitrary Python objects and/or user expecting a list to be returned).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions