1

Тема: Як працюйе множеня списку обйектів на число ?

for x in zip(*[iter(range(9))]*3):
    print(x)
# (0, 1, 2)
# (3, 4, 5)
# (6, 7, 8)

list(zip(*[iter(range(9))]*3))
# [(0, 1, 2), (3, 4, 5), (6, 7, 8)]

list(map(list, zip(*[iter(range(9))]*3)))
# [[0, 1, 2], [3, 4, 5], [6, 7, 8]]

for x in zip(*[iter(range(8))]*4):
    print(x)
# (0, 1, 2, 3)
# (4, 5, 6, 7)

list(map(list, zip(*[iter(range(8))]*4)))
# [[0, 1, 2, 3], [4, 5, 6, 7]]

Це шо ¿ масив ітераторів ([iter(range(9))]*3) містить не копії обйекта, а копії посиланя на 1 спільний ітератор ?

2

Re: Як працюйе множеня списку обйектів на число ?

Принаймні це було б правильно з точки зору оптимізації: чим менше копій об'єкта створюємо в роботі, тим швидше працює алгоритм.

Подякували: leofun011

3

Re: Як працюйе множеня списку обйектів на число ?

Так, там вказівники на елементи початкового списку. (див. cpython/Objects/listobject.c)
static PyObject *list_repeat(PyObject *aa, Py_ssize_t n)
  + static PyObject *list_repeat_lock_held(PyListObject *a, Py_ssize_t n)

    Py_ssize_t output_size = input_size * n;

    PyObject **dest = np->ob_item;
    if (input_size == 1) {
        PyObject *elem = a->ob_item[0];
        _Py_RefcntAdd(elem, n);
        PyObject **dest_end = dest + output_size;
        while (dest < dest_end) {
            *dest++ = elem;
        }
    }
    else {
        PyObject **src = a->ob_item;
        PyObject **src_end = src + input_size;
        while (src < src_end) {
            _Py_RefcntAdd(*src, n);
            *dest++ = *src++;
        }
        _Py_memory_repeat((char *)np->ob_item, sizeof(PyObject *)*output_size,
                                        sizeof(PyObject *)*input_size);
    }

static int list___init___impl(PyListObject *self, PyObject *iterable)
  + static int _list_extend(PyListObject *self, PyObject *iterable)
      + static int list_inplace_repeat_lock_held(PyListObject *self, Py_ssize_t n)

    Py_ssize_t output_size = input_size * n;

    PyObject **items = self->ob_item;
    for (Py_ssize_t j = 0; j < input_size; j++) {
        _Py_RefcntAdd(items[j], n-1);
    }
    _Py_memory_repeat((char *)items, sizeof(PyObject *)*output_size,
                      sizeof(PyObject *)*input_size);

Взнати як працюйе iter теж було корисно.