简体   繁体   中英

Add missing numbers in a list of integers sorted in ascending order

I am trying to implement a function that would insert any missing numbers in a list. The list is in ascending order with no repetitive elements.

This is my code so far:

def fill_in_numbers(lst):
    i=0
    while True:
        if lst[-1] - lst[i] !=1:
            lst.insert(i+1, lst[i]+1)
        i+=1
        if lst[-1] - lst[i]== 1:
            break
    return lst

So, for example, if the input is fill_in_numbers([12,15,19]) the expected output is [12,13,14,15,16,17,18,19] , or if the input is fill_in_numbers([-5,0,5]) the expected output is [-5,-4,-3,-2,-1,0,1,2,3,4,5] .

However, when I run my code the output I get for the first input is [12,13,14,15,16,17,18,15,19] and for the second one is [-5,-4,-3,-2,-1,0,1,2,3,4,0,5] .

What is wrong with my code?

The other answers give you the solution but do not explain why yours is not working. The problem you are having is that every time you loop (until you break), you are inserting a number into your list, without checking if that number is already in the list. This results in all other original list entries that are not an extremity being pushed all the way to the end of the list.

If you desire to use your original code, than the fix should be simply in the first condition:

def fill_in_numbers(lst):
    i=0
    while True:
        if lst[i+1] != lst[i] + 1:
             lst.insert(i+1, lst[i]+1)
        i+=1
        if lst[-1] - lst[i]== 1:
            break
    return lst

If the next lst element is indeed the sequential number, then the body of the first if statement is not executed, and the 'i' iterator is incremented, allowing the next loop to use this original number in the conditions and not an unnecessary duplicate.

This is not the cleanest python code, but not too bad for just starting :)

Take the first and last values (or min and max), throw all the old values away, and fill in new values using range :

>>> def fill_in_numbers(lst):
...     #n1 = min(lst)
...     n1 = lst[0]
...     #n2 = max(lst)
...     n2 = lst[-1]
...     lst[:] = range(n1, n2 + 1)
...     return lst
...

>>> fill_in_numbers([3, 8 , 12])
[3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

Without any complexity you can do in this way,

 def fill_in_numbers(lst):
        i=0
        lst = [a for a in range(lst[i],lst[-1]+1)]
    
        return lst
    
  print(fill_in_numbers([12,15,19]))

Your code is incorrect because when you insert a number into the list, you do not check if the number is already in the list.

I think the easiest way is to make a new list with range function and unpack it to a list.

def fill_in_numbers(lst):
    return [*range(lst[0], lst[-1]+1)]

or

def fill_in_numbers(lst):
    start = lst[0]
    end = lst[-1]
    return [*range(start, end + 1)]

Example:

print(fill_in_numbers([12, 15, 19])) # Output: [12, 13, 14, 15, 16, 17, 18, 19]
print(fill_in_numbers([-5, 0, 5])) # Output: [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]

As per your logic, you need to insert number in list if number is not present in list otherwise no need to insert number in list

def fill_in_numbers(lst):
    i=0
    while True:
        if lst[-1] - lst[i] !=1:
            if lst[i]+1 not in lst:
                lst.insert(i+1, lst[i]+1)
        i+=1
        if lst[-1] - lst[i]== 1:
            break
    return lst

Simple Approach

def fill_in_numbers(lst):
    return list(range(lst[0], lst[-1]+1))

You can try with this approach :

def fill_in_numbers(lst):
  new_list = []
  for i in range(len(lst)):
    new_list.append(lst[i])
    if i+1 < len(lst):
      [new_list.append(k) for k in range(lst[i]+1, lst[i+1])]
  return new_list


print(fill_in_numbers([12,15,19])) # --- Output --->>> [12, 13, 14, 15, 16, 17, 18, 19] 
print(fill_in_numbers([ -5,0, 5])) # --- Output --->>> [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]

The only change to the code shown in the question that is actually necessary is in the line:

        if lst[-1] - lst[i] !=1:

you need to change the -1 to i+1 , because you are comparing the list item with the next one, rather than the last one.

With that change, you get the desired result, given inputs that comply with the constraints.


Also you might want to consider getting rid of the return lst statement (the function will then return None ). Generally, it is advisable that the function should either modify the existing list or return a new list, but it is better not to both modify the existing list and also return it, because it can create confusion about how to use the function. In this case, you are modifying the existing list. So after removing the return statement, then when you call it you might do:

lst = [12,15,19]
fill_in_numbers(lst)
print(lst)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM