How to resolve "Valueerror: max() Arg is an Empty Sequence" error when the list is empty?

Asked

Viewed 253 times

1

This error appeared when I was testing my program, more precisely when the values of input do not satisfy the conditions imposed:

n = int(input())
listaVelocidade = []

for _ in range(n):
    velocidades = int(input())
    listaVelocidade.append(velocidades)
    classe1 = []
    classe2 = []
    classe3 = []

    for velocidade in listaVelocidade:
        if velocidade < 10:
            classe1.append(velocidade)

        elif velocidade >= 10 and velocidade < 20:
            classe2.append(velocidade)

        elif velocidade > 20:
            classe3.append(velocidade)

if None in classe1 or classe2 or classe3:
    classe1.append(0)
    classe2.append(0)
    classe3.append(0)

print(max(classe1), max(classe2), max(classe3))

Note that I put a condition to check if the list is empty but this did not work, also previously I tried to put a else and add 0 to the lists if the above conditions are not met.

Oobs: I ask you to test by placing, for example, 6 as the first input value and then a sequence of 1, another observation is that if no condition is satisfied, I have to return 0.

3 answers

2

This here:

if None in classe1 or classe2 or classe3:

Not does what you think you do. In fact, what you have are 3 conditions:

  • None in classe1: this checks out if None is on the list classe1 (that is, if None was previously inserted into the list). But since you only insert numbers, the None will never be on the list, so that condition will always be false
  • classe2: yes, a list (and any other value) can be used in a context boolean. In this case, if the list is empty, it is considered a false value, and if it is not empty, it is considered true.
  • classe3: ditto

Therefore, the first condition will always be false, but if classe2 or classe3 have at least one element, will be considered True and will enter the if, since an expression that has several conditions with or is considered true if any of the conditions is true (print the lists after this if and see for yourself classe2 or classe3 is not empty, a zero is always added).

And that’s why he doesn’t get into if when the lists classe2 and classe3 are empty: because an empty list is evaluated as False, and as already said, the first condition is also false because None was not added in classe1 (then all conditions are false and does not enter the if).


But honestly, what you thought you’d do is - in my opinion - a great gambit. If the idea is to return zero if the list is empty, there is no reason to add an element artificially just to avoid error. I find it simpler to check if the list is empty:

n = int(input())

classe1 = []
classe2 = []
classe3 = []
for _ in range(n):
    velocidade = int(input())
    if velocidade < 10:
        classe1.append(velocidade)
    elif velocidade < 20:
        classe2.append(velocidade)
    else:
        classe3.append(velocidade)

def maior(lista):
    if len(lista) == 0: # se a lista é vazia, retorna zero
        return 0
    return max(lista) # lista não é vazia, retorna o max()

print(maior(classe1), maior(classe2), maior(classe3))

I created a function to make it easy: it checks if the list is empty (if it is, returns zero), and if it is not, it uses max. That’s better than adding one more element. Of course we can also discuss whether it makes sense to return any artifical value (And if only zeros are typed, how will you know if zero is the highest value that was actually typed or if it fell in the case of empty list? Maybe it is the case of not returning anything and printing an error message, for example), but anyway, insert an artificial value "just for the max make no mistake" seems like a worse option.

I removed the list listaVelocidade, because it seems that it was not being used for anything (only to store the speeds, to only be inserted in one of the other lists, so it seems to me a little redundant; I found it simpler to insert the direct value in the respective lists).

And I created the lists only once, before the for. You were creating them inside the for, that is, at each iteration they were recreated again, which makes no sense. Create once outside the loop and inside it just insert the elements.

Note also the if's: if you didn’t enter the if velocidade < 10 is because the value is definitely greater than or equal to 10, so you don’t need to test this again in the elif.
And if you didn’t get into elif velocidade < 20, is because it is definitely greater than or equal to 20, so do not need to test again in the else:

if velocidade < 10:
    # se entrou aqui, é porque é menor que 10
    classe1.append(velocidade)
# se não entrou no if acima, é porque com certeza é >= 10, então não precisa testar de novo no elif
elif velocidade < 20:
    classe2.append(velocidade)
# se não entrou no if nem no elif, é porque com certeza é >= 20, então não precisa testar de novo
else:
    classe3.append(velocidade)

2

See the algorithm of your code:

Leia o número de entradas e coloque em n
Inicialize a lista de velocidades listaVelocidade

Itere sobre o número de entradas...
   Leia uma velocidade
   Inicialize a lista de classe de velocidade classe1 
   Inicialize a lista de classe de velocidade classe2
   Inicialize a lista de classe de velocidade classe3 
   Para cada velocidade em listaVelocidade
      Verifique se a velocidade é menor que 10
         Se sim a adicione velocidade em classe1
      Se não se a velocidade é maior ou igual a 10 e menor que 20
         Se sim a adicione velocidade em classe2
      Se não se a velocidade é maior que 20
         Se sim a adicione velocidade em classe3

Verifique se None está em classe1 ou classe2 não está vazia ou classe3 não está vazia
    Adicione 0 a classe1
    Adicione 0 a classe2
    Adicione 0 a classe3

Imprima o maior valor de classe1, o maior valor de classe2, o maior valor de classe3

Note that just after reading a speed the code restarts the lists classe1, classe2 and classe3 that is to each new speed inserted in the system the values entered previously are lost so every time it enters with a new speed it is necessary to reiterate the list of speeds and reclassify them.

During the reclassification of speeds there is another problem there is a condition that:

  • Checks if the speed is less than 10.
  • Checks whether the speed is greater than or equal to 10 and less than 20.
  • Checks if the speed is greater than 20.
  • But there is no condition which captures a speed of 20!

On the last check the condition:

Verifique se None está em classe1 ou classe2 não está vazia ou classe3 não está vazia

This expression doesn’t work the way you expect to see a very naive test:

>>> print(bool(None in [] or [] or []))
False

In other words, if classe1, classe2 and classe3 were empty lists the condition would not be met.

As a solution it would be better to rewrite your algorithm by removing the redundancies and improving the data structures thus avoiding having to repeat data a range of comparisons to cover the holes. To facilitate will be used a dictionary which is mapping structure in key/value form and the conditional expression which compares a condition and this is true returns the left side of the expression and false returns the right side.

#Inicicializa a estrutura de dados que abrigará e classificará as velocidade em classes.
velocidades = {"classe1":[0], "classe2":[0], "classe3":[0]}

#Lê a quantidade de entradas e itera essa quantidade...
for _ in range(int(input("Quantidade de dados: "))):
    v = int(input("Digite a velocidade: "))                         #...lê uma velocidade e armazena e v.
    c = "classe1" if v < 10 else "classe2" if v < 20 else "classe3" #...classifica a velocidade, se menor que 10 é classe1, 
                                                                    #se menor que 20 e maior ou igual a 10 é classe2,
                                                                    #o que sobrar(maior ou igual a 20) é classe3. 
    velocidades[c].append(v)                                        #...Adiciona a velocidade a sua respectiva classe.

print([max(velocidades[c]) for c in velocidades])                   #Itera pelas chaves dicionário velocidade obtendo e imprimindo o maior valor.

Test the example on ideone.

2

The mistake "Valueerror: max() Arg is an Empty Sequence" is indicating that some - or all - sequences are empty. For you to fix this problem you should change the block...

if None in classe1 or classe2 or classe3:
    classe1.append(0)
    classe2.append(0)
    classe3.append(0)

...for:

if len(classe1) == 0:
    classe1.append(0)
if len(classe2) == 0:
    classe2.append(0)
if len(classe3) == 0:
    classe3.append(0)

Another thing, your code is misspelled. Also, your last block elif is wrong.

A correct way to resolve this issue is:

n = int(input())
listaVelocidade = []

for _ in range(n):
    velocidades = int(input())
    listaVelocidade.append(velocidades)

classe1 = []
classe2 = []
classe3 = []

for velocidade in listaVelocidade:
    if velocidade < 10:
        classe1.append(velocidade)
    elif 10 <= velocidade < 20:
        classe2.append(velocidade)
    else:
        classe3.append(velocidade)

if len(classe1) == 0:
    classe1.append(0)
if len(classe2) == 0:
    classe2.append(0)
if len(classe3) == 0:
    classe3.append(0)

print(max(classe1), max(classe2), max(classe3))

Note that when executing this code, we should insert the amount of speeds that we will insert and then enter enter. Later, we must type each of the n-goodies speeds and, for each speed, press enter.

Having finished inserting all speeds, the code will sort the speeds, grouping them into classes. Later, each class will be checked and if any of them are empty, the value will be added 0 in the same.

Finally the maximum speed of each class will be displayed.

Browser other questions tagged

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