How to check if a list contains 3 consecutive numbers

Asked

Viewed 412 times

4

Insert a vector with 10 random integer values. Then check if there is a sequence of 3 consecutive numbers in the vector. Two values are consecutive if the difference is 1 unit

example:

A = [10, 5, 7, 9, 20, 16, 11, 12, 13, 3]

In this vector, there are 3 consecutive values: 11, 12 and 13

All I’ve got so far is this

C = []

A = [10, 5, 7, 9, 20, 16, 11, 12, 13, 3]

for i in range(len(A) - 1):

    if A[i] == A[i + 1] - 1:

        C.append(A[i])
        C.append(A[i + 1])

print(C)

4 answers

2

Well, for each element, you need to check the next 2 (i.e., for each position i, you need to check the positions i + 1 and i + 2). Then you must iterate up len - 2 instead of len - 1:

numeros = [10, 5, 7, 9, 20, 16, 11, 12, 13, 3]
for i in range(len(numeros) - 2):
    if numeros[i] + 1 == numeros[i + 1] == numeros[i + 2] - 1:
        print(f'Tem 3 números consecutivos: {numeros[i]}, {numeros[i + 1]}, {numeros[i + 2]}')
        break
else:
    print('não tem 3 números consecutivos')

In the for, just see if the position element i summed with 1 is equal to the position element i + 1, which in turn is equal to the element of the position i + 2 subtracted from 1. If it is, I print the numbers and interrupt the loop with break.

If you don’t have 3 consecutive numbers, it won’t reach the break and falls into else (yes, the else is from for, in Python this is perfectly possible).


I don’t know why you created the list C, because if the idea is only to know if you have or not, you would not need to store the numbers. But if you want, you can make a Slice to get the list of consecutive:

numeros = [10, 5, 7, 9, 20, 16, 11, 12, 13, 3]
for i in range(len(numeros) - 2):
    consecutivos = numeros[i:i + 3] # slice para pegar os elementos i, i + 1 e i + 2
    if consecutivos[0] + 1 == consecutivos[1] == consecutivos[2] - 1:
        break
else: # se não achou, deixa a lista de consecutivos vazia
    consecutivos = []

if consecutivos: # se a lista não está vazia
    print(f'Os números consecutivos são {", ".join(map(str, consecutivos))}')
else: # se a lista é vazia
    print('não tem 3 números consecutivos')

And there’s also the solution - medium over enginnered and based in this reply by Soen - using the module itertools:

from itertools import tee

def threes(iterator):
    a, b, c = tee(iterator, 3)
    next(b, None)
    next(c, None)
    next(c, None)
    return zip(a, b, c)

numeros = [10, 5, 7, 9, 20, 16, 11, 12, 13, 3]
for a, b, c in threes(numeros):
    if a + 1 == b == c - 1:
        consecutivos = [a, b, c]
        break
else:
    consecutivos = []

if consecutivos: # se a lista não está vazia
    print(f'Os números consecutivos são {", ".join(map(str, consecutivos))}')
else: # se a lista é vazia
    print('não tem 3 números consecutivos')

The idea is that tee generates 3 independent iterators from the list of numbers. As all point to the beginning of the list, I call next why b point to the second element and c point to the third. Then use zip which returns an iterator for the 3 generated iterators (a points to the first element, b for the second, and c to the third).

When iterating for the result of all this, I always have 3 consecutive numbers on the list, and then just do the same check of the previous examples. Like zip ends when the smallest iterator is finished, the loop ends correctly when I reach the last number.

1

A two-line numerical approach. Passo 1 locates what values have a rate of change equal to 1. Passo 2 test for value sequence True.

import numpy as np 
A = np.random.randint(0, 10, size=(10,)) 
print(A) 

out = (A[1:] - A[:-1]) == 1    # passo 1
out = out[1:] & out[:-1]       # passo 2

print(f"Tem 3 números consecutivos: {True in out}") 

Extra: For repeated sequences replace, in Passo 1, the value 1 for 0 and for decreasing sequences, replace the 1 for -1. The proposal follows the same idea of a discrete derivative.

1

If the goal is to identify all sequences of three consecutive integer numbers in a list, one option is to sequence comparison :

n = [-3, -2, -1, 10, 5, 7, 9, 20, 16, 11, 12, 13, 3]
result = []                                 #Inicializa a variável que receberá o resultado.
#Para todos elemento i,v na enumeração do primeiro ao antepenúltimo elemento n...
for i, v in enumerate(n[:-2]):  
  #...verifica se a fatia [n[i],n[i+1],n[i2]] for igual a lista de consecutivos [v,v+1,v+2]...
  if (c:=n[i:i+3]) == [*range(v, v+3)]:     
    result.append(c)                        #...se sim apensa a fatia ao resultado.

print(*result, sep="\n")                    #imprime o resultado

The algorithm creates a enumeration from the first to the last member of the list n and iterates, with i the index and v value , by this enumeration comparing the Slice formed by the three elements adjacent to n[i] with the list formed by the three consecutive numbers from v. If the comparison finds sequence equivalence, it shall be appended to result, if there is no equivalence pass the next comparison.

The same code above using comprehensilist on:

n = [-3, -2, -1, 10, 5, 7, 9, 20, 16, 11, 12, 13, 3]
l = [c for i, v in enumerate(n[:-2]) if (c:=n[i:i+3]) == [*range(v, v+3)]]
print(*l, sep="\n")

Both codes above result:

[-3, -2, -1]
[11, 12, 13]

0

Inside the loop I would do something like this:

if i+2 < len(A) -1:
   if A[i] == A[i+1] -1 and A[i] == A[i+2] - 2:
       contem_consecutivos = True

First I see if there are 2 numbers in front, if there is, it sees if the next number minus 1 is equal to the current number and if the after the next minus 2 is also, they are consecutive

Browser other questions tagged

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