Return the missing element from a list of integer numbers

Asked

Viewed 406 times

1

Make a function called missing that, given a list with N 1 integers numbered from 1 to N, finds out which integer of this range is missing. I can’t find a code that covers any list of integers.

def faltante(L: List[int]):
''' teste '''
    posicao = 0
    while L[posicao] < len(L):
        if posicao+1 == L[posicao]:
            posicao = posicao + 1
        break
    return posicao+1

Exit

print(faltante([1, 2, 3, 5, 6, 7, 8]))

returns 2, expected 4

  • Marco, good afternoon! Enter in your code an example of a list you want to test and the expected result. Hugs!

  • The numbers will always be in ascending order?

  • Yes. They’ll be in ascending order

  • Only one number will be missing or more than one number may be missing from the list?

4 answers

5

You can compare if the next element is the sum of the current element + 1, if different we add the current item + 1 (which should be the real value) to the list, which is within the function, and at the end of the execution we return this list:

def faltante(lista):
    lst_return = []    
    
    for i in range(len(lista) - 1): 
        if lista[i + 1] != lista[i] + 1 :
            lst_return.append(lista[i] + 1)
            
    return lst_return

Exit:

print(f'Números faltantes: {faltante([1,2,3,5,6,7,8,10])}')
Números faltantes: [4, 9]

An alternative to lists like [1, 5, 7, 9]:

is to use the range:

lst_return.append(list(range(lista[i] + 1, lista[i + 1])))

Exit:

print(f'Números faltantes: {faltante([1, 5, 7, 9])}')
Números faltantes: [[2, 3, 4], [6], [8]]

A more general way:

def faltante(lista):
    lst_return = []    
        
    if lista[0] != 0:
        lst_return.append(list(range(0, lista[0])))
        
    for i in range(len(lista) - 1):    
        if lista[i + 1] != lista[i] + 1 :
            lst_return.append(list(range(lista[i] + 1, lista[i + 1])))
            
    return lst_return

Exit:

print(f'Números faltantes: {faltante([5, 7, 9])}')
Números faltantes: [[0, 1, 2, 3, 4], [6], [8]]

4

To verify ALL the numbers that may be missing from a list whichever, just use the code below.

NOTE: This code may include any lists of integers - increasing, decreasing, alternating, with positive values, with negative values, with null values and with positive, negative and null values.

def faltante(lis):
    menor = min(lis)
    maior = max(lis)
    faltando = list()
    for c in range(menor, maior + 1):
        if c not in lis:
            faltando.append(c)
    return faltando


numeros = list(map(int, input('Digite alguns números: ').split()))

print(f'Os números faltantes são:\n{faltante(numeros)}')

Note that when we execute this code we receive the following message: Digite alguns números: . Right now we must type all the number we desire, in the same line, separated for a single space and press enter.

After inserting the values, they will be mounted in the list números and then it is passed as a parameter to the function faltante. Getting there, is calculated the menor and maior value of that list. Subsequently, the for will travel the range(menor, maior + 1) and, with the aid of the block if, is checked whether each element of the respective interaction does not belong to the list - parameter lis. If the item does not belong to the list, it is added to the list faltando.

After these operations the list of missing numbers is displayed.

Let’s test the execution of the code?

Example 1:

Let’s enter the values...

1 2 3 5 6 7 8 10

The exit will be:

[4, 9]

Example 2:

Let’s enter the values...

1 5 7 9

The exit will be:

[2, 3, 4, 6, 8]

Example 3:

Let’s enter the values:

1 12 13 15 17 20

The exit will be:

[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 14, 16, 18, 19]

Note that in both examples, the code was able to verify and display ALL the values MISSING in a single list and in ascending order.

Something else, when calculating the menor and the maior list value already enabled the function to work with values that are also not in order - rising or decreasing.

Example 4:

Let’s enter the values:

12 9 2 5 18

The exit will be:

[3, 4, 6, 7, 8, 10, 11, 13, 14, 15, 16, 17]

Example 5:

Let’s type in the figures:

4 20

The exit will be:

[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

Example 6:

Let’s enter the values:

-10 -3 6 12

The exit will be:

[-9, -8, -7, -6, -5, -4, -2, -1, 0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11]

Summary

This code is able to identify and display all the missing values of a list of numbers whole - positive, negative and null - regardless of the order - ascending, decreasing or alternating - that the values are.

3

Like looks like be an exercise, "probably want" you do with a loop simple. But just to leave registered, you can resolve using set:

def faltante(numeros):
    # intervalo contendo todos os números possíveis (baseado na lista de números)
    # vai do menor valor existente da lista até o maior
    intervalo = range(min(numeros), max(numeros) + 1)
    return list(set(intervalo) - set(numeros))

Or, putting it all together in one line:

def faltante(numeros):
    return list(set(range(min(numeros), max(numeros) + 1)) - set(numeros))

The idea is to generate 2 set's:

  • the first set contains all possible numbers. I am considering that the range goes from the smallest number existing in the list to the largest number existing in the list. This does not cover cases where the first or last one is missing. For example, if the list is [2, 5, 8], Number one is missing? Or do I only consider the numbers from the 2? I am considering that it is the second case (which is also what the other answers have done).

    In fact, there is also the limitation of not considering the case where the largest number is missing: if the list is [1,2,3], o 4 is missing? This solution - and the other answers as well - consider that not (although in a more general case as [2, 5, 9], How to know if the 10 is missing or not? In that case I think it’s best to consider that 9 is the upper limit - but right below I leave an alternative to solve this).

  • the second set contains only the numbers in the list.

Subtracting the set's, we have the missing numbers, and I turn the set resulting in list (although it is not necessary, if you just want the numbers, whatever the structure in which they are returned).

It is worth remembering that a set does not guarantee the order of the elements, so the list will not always return the numbers in order (but if you want, you can use sorted to return the ordered list):

def faltante(numeros):
    return sorted(list(set(range(min(numeros), max(numeros) + 1)) - set(numeros)))

About the minimum and maximum limit problem, you can still do this way:

def faltante(numeros, minimo = None, maximo = None):
    if minimo is None:
        minimo = min(numeros)
    if maximo is None:
        maximo = max(numeros)
    intervalo = range(minimo, maximo + 1)
    return sorted(list(set(intervalo) - set(numeros)))

print(faltante([1, 2, 3, 5])) # 4

# falta o 5
print(faltante([1, 2, 3, 4], maximo=5))

# falta o 1
print(faltante([2, 3, 4, 5], minimo=1)) # 1

# falta o -1, 0 e 1, além do 6 e 7
print(faltante([2, 3, 4, 5], minimo=-1, maximo=7)) # [-1, 0, 1, 6, 7]

Thus, I can parameterize the values that are considered. For example, in a list like [1,2,3], i can indicate that the 4 is missing by passing the parameter maximo=4 - and if I don’t pass any value, it uses the previous logic of taking the lowest and highest value of the list as the limits.

Of course this algorithm is not very efficient, since call max and min separately traverses the list 2 times, and the very creation of set's (and the ordering of the list at the end) also have an additional cost.


But in the specific case of the financial year (at all times are numbers from 1 to N, only one of them for sure is missing and they will always be in ascending order), can do so:

def faltante(numeros):
    if numeros[0] != 1: # ver se o 1 está faltando
        return 1
    for i, n in enumerate(numeros):
        if i == len(numeros) - 1 or n + 1 != numeros[i + 1]:
            return n + 1

print(faltante([1, 2, 3, 5])) # 4

# falta o 5
print(faltante([1, 2, 3, 4])) # 5

# falta o 1
print(faltante([2, 3, 4, 5])) # 1

I use enumerate to iterate through the elements and their respective indexes. Then, just see if I arrived at the last element (in case the last is missing), or if the next element is not equal to the current + 1. In both cases the missing element is the current + 1.

Only before the loop must include a special check in the case of 1 be missing.

But if the idea is to have a more general solution, just use set or any of the algorithms of the other answers.

  • 1

    I may have analyzed wrong (sleep), but in the solution with sets it is risky to use max(numeros) + 1 as an upper limit as the list is numbered from 1 to N, if N is not on the list itself its solution would consider only up to N-1, no?

  • @Woss Yes, there is this limitation. I think there is not much way. If the idea is to consider only the case of the exercise (always numbers from 1 to N, only one is missing), the loop seems to me the best option. But in a generic case like [2, 7, 9], No way to know what the maximum limit is (is 9? some other higher number?) Anyway, I added a few remarks about that, thank you!

  • 1

    It could receive N per parameter as well, since it parameterizes the xD problem

  • @Woss But of course! I think I’m sleepy too, I should have thought about it before. I updated the reply, thanks again :-)

2

See a program based on yours, with some changes:

def faltantes(L):
    if L:                             # se L tem conteudo...
        elemento = L[0]               # ...pego o primeiro elemento
        posicao = 1                   # e aponto para o 2o elemento
        while posicao < len(L):       # enquanto posicao nao chegar ao fim de L
            # se elemento *não* for antecessor a L na posicao atual...
            if (elemento + 1) < L[posicao]: 
                elemento += 1         # incremento elemento...
                yield elemento        # ... e devolvo um gerador com este elemento
            else:                     # senao...
                elemento = L[posicao] # ...tomo o elemento atual e
                posicao += 1          # ando para a proxima posicao de L
    
# programa
print('Primeira lista')
for i in faltantes([1,2,3, 5,6,7,8]):
  print(i)

print('Segunda lista')
for i in faltantes([]):
  print(i)

print('Terceira lista')
for i in faltantes([2, 4,5, 7, 9]):
  print(i)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.