Check that all items in the list are equal

Asked

Viewed 1,031 times

6

I have a list of times containing the values of times of several cars and I would like to know how do I know if all these values are equal

I thought to compare each value with its later, ie compare the value of tempos[i] with the value of tempos[i+1] and store the result of these comparisons, i.e., True or False in any other list and then check that all elements of that other list are equal to True or not.

n = 4
tempos = [0.5, 1.3, 2.5, 3.4]

for i in range(0, len(tempos)):
    if(tempos[i] == tempos[i+1]):
       comparações.append(tempos[i] == tempos[i+1])

But there’s always a mistake in the line: if(tempos[i] == tempos[i+1])

  • Your vector has 4 positions ranging from 0 to 3, when you do i+1, you are getting the next value, but what happens you fall at the last position, and try to get the 3+1 position, which does not exist?

5 answers

11


One way you can do it is the set(), where when a list is converted to a set, duplicate elements are removed, so if duplicates are removed, the size of that set is 1, implying that all are equal, otherwise it implies that there are different values in the list.

Example:

tempos_diferentes = [0.5, 1.3, 2.5, 3.4]
tempos_iguais = [1.0, 1.0, 1.0, 1.0]

len(set(tempos_iguais)) == 1
#Retorna True

len(set(tempos_diferentes)) == 1
#Retorna False

6

A SUPER SIMPLE SOLUTION

Turn the list into a set. Should the size of the set generated be 1, so all items are equal.

Example

>>> l1 = [1, 2, 3, 1, 1, 2, 2]
>>> print(len(set(l1)) == 1)
False

>>> l2 = ["banana", "banana", "banana", "banana"]
>>> print(len(set(l2)) == 1)
True

Another solution

I really like to use the Counter library collections.

The Counter counts the items of an iterable and returns a dictionary, where the key is the item and the value is the quantity. See below

from collections import Counter

uma_lista = [1, 2, 1, 2, 1, "banana", 1, "banana"]

c = Counter(uma_lista)

print(c)

The result will be:

Counter({1: 4, 2: 2, 'banana': 2})

That is, 4 items 1, 2 items 2 and 2 items banana.

Let’s get to your question

from collections import Counter

def todos_iguais(lista):
    c = Counter(lista)
    quantidade = list(c.values())[0]  # primeiro e talvez único valor da lista
    return quantidade == len(lista)  # se a quantidade for igual, todos os itens são iguais.

Update Of course if the amount of items on the list, ie len(c.values()) is equal to 1, all items are equal.

So just call the function by passing a list.

l1 = [1, 2, 3, 4, 2, 1]
print(todos_iguais(l1))    # o resultado será False

Note that this solution works for lists with other types than whole.

l2 = ["banana", "banana", "banana", "banana"]
print(todos_iguais(l2))   # o resultado será True

I hope I’ve helped

4

The problem is that when i arrives at the last element, i + 1 tries to access an element that does not exist. Then you should only go to the penultimate element.

Another point is that you don’t need to create another list with the result of the comparisons, only to see if all the results are True. To check if all the results are true, just use all:

tempos = [0.5, 1.3, 2.5, 3.4]
todos_iguais = all(tempos[i] == tempos[i + 1] for i in range(len(tempos) - 1))
print(todos_iguais) # False

It is worth remembering that all returns True if the list is empty. If you want it to return False for this case, have to treat separately:

# retorna False se a lista for vazia (se não for vazia, usa o mesmo código anterior)
todos_iguais = not tempos or all(tempos[i] == tempos[i + 1] for i in range(len(tempos) - 1))

But as the idea is to know if all the elements are equal, it does not matter if you are comparing the element with the next or with any other. So you could compare them all to the first:

# vê se a lista é vazia ou se todos são iguais ao primeiro
todos_iguais = not tempos or all(tempos[0] == x for x in tempos)

Now it is important to see if the list is empty, otherwise it will give error when trying to access the first element.

Of course a useless comparison will be made at the beginning (the first element will be compared to itself), but if you want you can do:

todos_iguais = not tempos or all(tempos[0] == x for x in tempos[1:])

For so I use only the second element hereafter in for. I just don’t know if it’s worth creating another list just to avoid a comparison.

Also note that at no time do you need the variable n.


Another alternative - maybe half over Engineered - is to use itertools.groupby. Including, in the own documentation has the "recipe" to detect if all elements are equal:

from itertools import groupby

tempos = [0.5, 1.3, 2.5, 3.4]
g = groupby(tempos)
todos_iguais = next(g, True) and not next(g, False)

The idea is that groupby groups consecutive elements that are equal in a single group. By calling next the first time, it returns the first group. If the list only has equal elements, there will not be a second group, and therefore the second call of next returns the second parameter entered, which in this case is False (that is, I am checking if the first group exists and if the second group does not exist, which only occurs if all elements are equal).

This code also returns True to empty list. If you want it to return False for this case, just change the first call to next(g, False).

3

You can make a function that checks if the next number is equal to the current number, if different already returns as soon as the list is not fully equal(False), otherwise if the for is until the end of the list it returns (True).

Entrances:

tempos = [0.5, 1.3, 2.5, 3.4]
tempo1 = [1, 1, 1, 1]
tempo2 = [1, 1, 2, 2]

Function:

def verifica(lista):
    for i in range(len(lista) - 1): 
        # caso o próximo número seja diferente ja retornamos com False.
        if(lista[i] != lista[i + 1]): 
            return False 
    return True # caso chegue ao final da lista, retornamos True.

Exit:

verifica(tempos)
False

verifica(tempo1)
True

verifica(tempo2)
False

About your code you did not initialize a comparisons variable. The index error if gives because you compare the current element + 1, you try to access at the end of the iteration an element that does not exist.

Correcting his code would look something like this:

tempos = [0.5, 1.3, 2.5, 3.4]
comparacoes = []
for i in range(0, len(tempos) -1): 
    if(tempos[i] == tempos[i + 1]): 
        comparacoes.append(tempos[i])

Only this code doesn’t do what you want it to do. Your code will check if the current element is equal to the next and if it is equal it adds the comparison list, if it is not equal it does nothing.

3

Another way to resolve this issue is by using function with the help of conversion from list to set. This way the code will be:

def valores_iguais(lis):
    if len(set(lis)) == 1:
        return True
    return False


tempos = [0.5, 1.3, 2.5, 3.4]

print(valores_iguais(tempos))

Note that this code sends the list times as a parameter for the function equals(). Getting there, the block if check whether the size of the list to seven is equal to 1. If positive, the return of the function will be True and otherwise the return of the function will be False.

If you prefer you can use the approach resulting from the comparison between list size times and the counting of some list element time. In this way we can implement the following code:

def elementos_identicos(li):
    return True if len(li) == li.count(li[0]) else False


lista = [0.5, 1.3, 2.5, 3.4]

print(elementos_identicos(lista))

In this code list is passed as a parameter to the function elements_identicos(). From that moment the return of the function will be True if the length of list is equal to the count of any of the elements of list. Otherwise the return will be False.

In this example I compared Len(li) with li.Count(li[0]), that is, the size of the list with the amount of elements that have value equal to the index element 0.

Browser other questions tagged

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