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.

Asked By: TomS

||

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]
Answered By: Unmitigated

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)
Answered By: PHPWork
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.