Inserting into a sorted list respecting sorting and avoiding duplicates
Question:
I know the trick to append to a list, convert it to a set to eliminate duplicates, convert it back to a list and apply sorting.
I would like to avoid this post-processing (if an alternative approach is more efficient).
So I am wondering if there is a direct way to insert into a sorted list while always respecting sorting and avoiding duplicates. As an example, inserting 3 into [1, 2, 4] shall yield [1, 2, 3, 4], and inserting 3 into [1, 3, 4] shall yield [1, 3, 4].
Is there a function for lists or aby other specific data structure available?
Is this more efficient than the usual approach „append – eliminate duplicates – sort“?
The length of the resulting list is typically < 10, the attempts to insert < 100 (so most inserts will fail), the function is called ~ 10^6 times. The data to be inserted are integers, so comparison is cheap.
Answers:
You can use bisect.bisect_left
to find the insertion point, then check if the element at that point is not the element you want to insert before calling list.insert
to add it.
Note that it is O(log N)
to find the insertion point, but O(N)
to insert into an arbitrary position.
import bisect
l = [1,2,4]
x = 3
i = bisect.bisect_left(l, x)
if i >= len(l) or l[i] != x:
l.insert(i, x)
print(l) # [1, 2, 3, 4]
Try this:
import bisect
def insert_into_sorted_list(sorted_list, element):
# Find the position where the element should be inserted
position = bisect.bisect_left(sorted_list, element)
# Check if the element is already in the list
if position == len(sorted_list) or sorted_list[position] != element:
# If not, insert the element at the appropriate position
sorted_list.insert(position, element)
I know the trick to append to a list, convert it to a set to eliminate duplicates, convert it back to a list and apply sorting.
I would like to avoid this post-processing (if an alternative approach is more efficient).
So I am wondering if there is a direct way to insert into a sorted list while always respecting sorting and avoiding duplicates. As an example, inserting 3 into [1, 2, 4] shall yield [1, 2, 3, 4], and inserting 3 into [1, 3, 4] shall yield [1, 3, 4].
Is there a function for lists or aby other specific data structure available?
Is this more efficient than the usual approach „append – eliminate duplicates – sort“?
The length of the resulting list is typically < 10, the attempts to insert < 100 (so most inserts will fail), the function is called ~ 10^6 times. The data to be inserted are integers, so comparison is cheap.
You can use bisect.bisect_left
to find the insertion point, then check if the element at that point is not the element you want to insert before calling list.insert
to add it.
Note that it is O(log N)
to find the insertion point, but O(N)
to insert into an arbitrary position.
import bisect
l = [1,2,4]
x = 3
i = bisect.bisect_left(l, x)
if i >= len(l) or l[i] != x:
l.insert(i, x)
print(l) # [1, 2, 3, 4]
Try this:
import bisect
def insert_into_sorted_list(sorted_list, element):
# Find the position where the element should be inserted
position = bisect.bisect_left(sorted_list, element)
# Check if the element is already in the list
if position == len(sorted_list) or sorted_list[position] != element:
# If not, insert the element at the appropriate position
sorted_list.insert(position, element)