Список подходов:
In [122]: alist=[1,3,5]
In [123]: for i,j in zip([1,3],[2,4]):
...: alist[i:i] = [j]
...:
In [124]: alist
Out[124]: [1, 2, 3, 4, 5]
np.insert
- это сложная функция, использующая разные подходы в зависимости от ввода индексов.Но в таком случае используется подход логической маски:
In [126]: arr = np.array([1,3,5])
In [127]: res = np.zeros(5, int) # 5 is len(arr)+len([2,4])
In [128]: mask = res.astype(bool)
In [129]: mask[[1,3]] = True
In [130]: mask
Out[130]: array([False, True, False, True, False])
In [131]: res[mask] = [2,4]
In [132]: res[~mask] = arr
In [133]: res
Out[133]: array([1, 2, 3, 4, 5])
mask
определяет, куда должны идти новые значения, и ~mask
, куда идут оригиналы.
insert
предполагает, что индексы даны относительно исходного массива, а не цели.Чтобы сделать то же самое, ему нужно дать [1,2]
, другими словами после arr[1]
и arr[2]
.insert
настроит [1,2]
на [1,3]
для использования вышеуказанного подхода маскирования.@ Ответ Дивакара берет ваш [1,3]
и преобразует его в [1,2]
, которого ожидает insert
.По сути, он компенсирует смещение, которое обычно добавляет insert
.
Если мы использовали [1,2]
(индексы относительно списка источников), итерация списка, которую я использовал выше, неверна.Он не учитывает тот факт, что список увеличивается после вставки 2
:
In [134]: alist=[1,3,5]
In [135]: for i,j in zip([1,2],[2,4]):
...: alist[i:i] = [j]
In [136]: alist
Out[136]: [1, 2, 4, 3, 5]
Чтобы компенсировать это, обычная хитрость заключается в вставке в обратном порядке:
In [137]: alist=[1,3,5]
In [138]: for i,j in zip([1,2][::-1],[2,4][::-1]):
...: alist[i:i] = [j]
In [139]: alist
Out[139]: [1, 2, 3, 4, 5]