Use the insort function of the bisect module:
import bisect
a = [1, 2, 4, 5]
bisect.insort(a, 3)
print(a)
Output
[1, 2, 3, 4, 5]
For more complicated usage, check key parameter for insort method
import bisect
a = [{"key": 1}, {"key": 3}]
bisect.insort(a, {"key": 2}, key=lambda x: x["key"])
print(a)
Output
[{"key": 1}, {"key": 2}, {"key": 3}]
Answer from stanga on Stack OverflowInsert an item into sorted list in Python - Stack Overflow
python - In place insertion into list (or array) - Stack Overflow
Lists in Python: .append() v. .insert()
What is the Time complexity (Big O) for insertion of an element in the end of an Array?
Videos
Use the insort function of the bisect module:
import bisect
a = [1, 2, 4, 5]
bisect.insort(a, 3)
print(a)
Output
[1, 2, 3, 4, 5]
For more complicated usage, check key parameter for insort method
import bisect
a = [{"key": 1}, {"key": 3}]
bisect.insort(a, {"key": 2}, key=lambda x: x["key"])
print(a)
Output
[{"key": 1}, {"key": 2}, {"key": 3}]
Hint 1: You might want to study the Python code in the bisect module.
Hint 2: Slicing can be used for list insertion:
>>> s = ['a', 'b', 'd', 'e']
>>> s[2:2] = ['c']
>>> s
['a', 'b', 'c', 'd', 'e']
Insert those values in backwards order. Like so:
original_list = [0, 1, 2, 3, 4, 5, 6, 7]
insertion_indices = [1, 4, 5]
new_numbers = [8, 9, 10]
new = zip(insertion_indices, new_numbers)
new.sort(reverse=True)
for i, x in new:
original_list.insert(i, x)
The reason this works is based on the following observation:
Inserting a value at the beginning of the list offsets the indexes of all other values by 1. Inserting a value at the end though, and the indexes remain unchanged. As a consequence, if you start by inserting the value with the largest index (10) and continue "backwards" you would not have to update any indexes.
Being NumPy tagged and since input is mentioned as list/array, you can simply use builtin numpy.insert -
np.insert(original_list, insertion_indices, new_numbers)
To roll out the theory as a custom made one (mostly for performance), we could use mask, like so -
def insert_numbers(original_list,insertion_indices, new_numbers):
# Length of output array
n = len(original_list)+len(insertion_indices)
# Setup mask array to selecrt between new and old numbers
mask = np.ones(n,dtype=bool)
mask[insertion_indices+np.arange(len(insertion_indices))] = 0
# Setup output array for assigning values from old and new lists/arrays
# by using mask and inverted mask version
out = np.empty(n,dtype=int)
out[mask] = original_list
out[~mask] = new_numbers
return out
For list output, append .tolist().
Sample run -
In [83]: original_list = [0, 1, 2, 3, 4, 5, 6, 7]
...: insertion_indices = [1, 4, 5]
...: new_numbers = [8, 9, 10]
...:
In [85]: np.insert(original_list, insertion_indices, new_numbers)
Out[85]: array([ 0, 8, 1, 2, 3, 9, 4, 10, 5, 6, 7])
In [86]: np.insert(original_list, insertion_indices, new_numbers).tolist()
Out[86]: [0, 8, 1, 2, 3, 9, 4, 10, 5, 6, 7]
Runtime test on a 10000x scaled dataset -
In [184]: original_list = range(70000)
...: insertion_indices = np.sort(np.random.choice(len(original_list), 30000, replace=0)).tolist()
...: new_numbers = np.random.randint(0,10, len(insertion_indices)).tolist()
...: out1 = np.insert(original_list, insertion_indices, new_numbers)
...: out2 = insert_numbers(original_list, insertion_indices, new_numbers)
...: print np.allclose(out1, out2)
True
In [185]: %timeit np.insert(original_list, insertion_indices, new_numbers)
100 loops, best of 3: 5.37 ms per loop
In [186]: %timeit insert_numbers(original_list, insertion_indices, new_numbers)
100 loops, best of 3: 4.8 ms per loop
Let's test out with arrays as inputs -
In [190]: original_list = np.arange(70000)
...: insertion_indices = np.sort(np.random.choice(len(original_list), 30000, replace=0))
...: new_numbers = np.random.randint(0,10, len(insertion_indices))
...: out1 = np.insert(original_list, insertion_indices, new_numbers)
...: out2 = insert_numbers(original_list, insertion_indices, new_numbers)
...: print np.allclose(out1, out2)
True
In [191]: %timeit np.insert(original_list, insertion_indices, new_numbers)
1000 loops, best of 3: 1.48 ms per loop
In [192]: %timeit insert_numbers(original_list, insertion_indices, new_numbers)
1000 loops, best of 3: 1.07 ms per loop
The performance just shoots up, because there's no runtime overhead on conversion to list.
Hello. I was learning lists and its formats and stuff like that. I soon came across .append() method and .insert() method. So far with my tests, they but work quite similarly to each other. However, I soon found out that you can not add any elements in the middle of a list using the .append(), but you can insert any new elements in the middle of the list using .insert().
Thus, what is the difference between .append() method and .insert() method?
Thank you.
Assume I have a code:
arr1=array("i", [1, 2, 3, 4, 5])
I just wanted to ask what would be the time complexity for inserting an element at the end of the array by using the code:
arr1.insert(5,6)
output: array('i', [1, 2, 3, 4, 5, 6])
Although, I found online that Big O is O(1) but I don't get it. Initially my array was of fixed sized(5) and if I need to add a new element, I am essentially copying the old array [1,2,3,4,5] and pasting it in a new memory location with an empty space at the end so that I could add [6] in the end. This is my understanding, if this is right how is O(1) correct? shouldn't it be more?
Edit: It's O(n)