How to find missing elements between two elements in a list in Python?

Question:

I have a list as follows:

['1', '5', '6', '7', '10']

I want to find the missing element between two elements in the above list. For example, I want to get the missing elements between '1' and '5', i.e. '2', '3' and '4'. Another example, there are no elements between '5' and '6', so it doesn’t need to return anything.

Following the list above, I expect it to return a list like this:

['2', '3', '4', '8', '9']

My code:

# Sort elements in a list
input_list.sort()

# Remove duplicates from a list
input_list = list(dict.fromkeys(input_list))

How to return the above list? I would appreciate any help. Thank you in advance!

Asked By: My Car

||

Answers:

If you iterate in pairs, it is easy to detect and fill in the gaps:

L = ['1', '5', '6', '7', '10']
result = []
for left, right in zip(L, L[1:]):
    left, right = int(left), int(right)
    result += map(str, range(left + 1, right))
Answered By: wim

I would use the range() function to generate the missing numbers, and maybe use itertools.pairwise() to easily compare to the previous number. Since Python 3.10, pairwise is better than zip(arr, arr[1:]) because pairwise is implemented in the C layer, and does not make a copy of lists.

import itertools
arr = ['1', '5', '6', '7', '10']

new_arr = []

for p, c in itertools.pairwise(arr):
    prev, curr = int(p), int(c)
    if (prev + 1) != curr:
        new_arr.extend([str(i) for i in range(prev + 1, curr)])
Answered By: Dash

Using a classic for loop and range() method and also for one-liner fans:

arr = ['1', '5', '6', '7', '10']
ans = []

for i in range(len(arr) - 1): ans += map(str, list(range(int(arr[i]) + 1, int(arr[i + 1]))))
    
print(ans)

outputs: ['2', '3', '4', '8', '9']

Answered By: Damzaky

If performance is not an issue, you can use a simple nested for loop:

input_list = ['1', '5', '6', '7', '10']

missing_list = []

for ind in range(0, len(input_list)-1):

    el_0 = int(input_list[ind])
    el_f = int(input_list[ind+1])

    for num in range(el_0 + 1, el_f):
        if num < el_f:
            missing_list.append(str(num))

The above assumes that the numbers are integers. The first loop is something not recommended – the loop iterates using the length of the list instead of constructs like enumerate. I used it here for its simplicity.

Answered By: atru

You could use a combination of range and set and skip iteration altogether.

#original data
data = ['1', '5', '6', '7', '10']

#convert to list[int]
L    = list(map(int, data))

#get a from/to count
R    = range(min(L), max(L)+1)

#remove duplicates and convert back to list[str]
out  = list(map(str, set(R) ^ set(L)))

print(out)
Answered By: OneMadGypsy
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.