Предположим, что у меня есть два списка с именами a и b обоих размеров n, и я хочу выполнить следующую операцию установки среза с k На Сложности времени вики-страницы Python говорится, что сложность настройки среза равна O (n + k). ) где k - длина среза. Я просто не могу понять, почему это не просто O (k) в вышеуказанной ситуации. Я знаю, что срезы возвращают новый список, так что это O (k), и я знаю, что список хранит свои данные непрерывно, поэтому вставка элемента в середину заняла бы O (n) времени. Но вышеуказанная операция может быть легко выполнена за O (k) время. Я что-то пропустил? Кроме того, есть ли документация, где я могу найти подробную информацию о таких проблемах? Должен ли я посмотреть на реализацию CPython? Спасибо.a[:k] = b[:k]
3 ответа
O (n + k) - это средний регистр , который включает необходимость увеличивать или уменьшать список, чтобы отрегулировать количество вставленных элементов для замены исходного среза.
В вашем случае, когда вы заменяете срез равным количеством новых элементов, реализация занимает всего O (k) шагов. Но с учетом всех возможных комбинаций количества вставленных и удаленных элементов, случай средний должен переместить n оставшихся элементов в списке вверх или вниз.
См. list_ass_slice
функцию для точного реализация.
Вы правы, если хотите узнать точные детали, лучше использовать источник. Реализация настройки среза для CPython: в listobject.c .
Если я правильно прочитал, это будет ...
- Подсчитайте, сколько новых элементов вы вставляете (или удаляете!)
- Сдвиньте n существующих элементов списка на достаточное количество мест, чтобы освободить место для новых элементов, в худшем случае - время O (n) (когда каждый элемент списка должен быть смещен).
- Скопируйте новые элементы в только что созданное пространство, потратив O (k) времени.
Это составляет в целом O (n + k).
Конечно, ваш случай, вероятно, не самый худший: вы изменяете последние k элементов списка, поэтому может не потребоваться смещение вообще, что снижает сложность до ожидаемой O (k). Однако это не так в целом.
Я могу ответить на вторую часть вашего вопроса, вместо этого использовать Numpy, это намного проще, и по своему опыту я не вижу повышения скорости при использовании CPython для индексации, поскольку Numpy был сильно оптимизирован для векторизации и индексации.
Похожие вопросы
Новые вопросы
python
Python - это многопарадигмальный, динамически типизированный, многоцелевой язык программирования. Он разработан для быстрого изучения, понимания и использования, а также для обеспечения чистого и единообразного синтаксиса. Обратите внимание, что Python 2 официально не поддерживается с 01.01.2020. Тем не менее, для вопросов о Python, связанных с версией, добавьте тег [python-2.7] или [python-3.x]. При использовании варианта Python (например, Jython, PyPy) или библиотеки (например, Pandas и NumPy) включите его в теги.