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!
CodePudding user response:
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)
CodePudding user response:
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.
CodePudding user response:
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)])
CodePudding user response:
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))
CodePudding user response:
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']