Error involving Nonetype

Asked

Viewed 244 times

1

I made a very simple code to simulate lines in python:

lista = []
def a(lista): return lista.append(str(input('Nome: ')).lower().strip())
def b(lista: list):
    if len(lista) == 0:
        print('A lista está vazia, impossível a remoção de item.')
    else:
        av = lista.pop(len(lista)-1)
        print(f'Item {av} foi removido da lista.')
    return lista
dicio = {'i': a, 'p': b, 'x': 'esta parte não importa'}
while True:
    opção = str(input('''O que deseja fazer?
- [i] para inserir um nome na lista.
- [p] para excluir o primeiro item da lista.
- [x] para encerrar o programa.
''')).lower().strip()
    while True:
        if opção in dicio: break
        opção = str(input('Opção inválida, tente novamente:\n')).lower().strip()
    if opção == 'x': break
    lista = dicio[opção](lista)

The problem is that after using a few times this error message appears:

TypeError: object of type 'NoneType' has no len()

or that:

AttributeError: 'NoneType' object has no attribute 'append'
  • The method append of a list does not return value, it modifies the list "in-place". To return the list, first do the append and in the next line return the same.

1 answer

2


The problem is here:

def a(lista): return lista.append(str(input('Nome: ')).lower().strip())

The error occurs because append returns None:

lista = []
result = lista.append(1)
print(result) # None

That is, the function returns None. So if the function a be called here:

lista = dicio[opção](lista)

lista will become None (and no longer the original list) and there occurs the indicated error (you try to pass None for len or call append in it).


As both functions modify the list itself internally, it would not need to return anything, just call them and that’s it:

# funções não precisam retornar
def a(lista):
    lista.append(input('Nome: ').lower().strip())

def b(lista):
    if len(lista) == 0:
        print('A lista está vazia, impossível a remoção de item.')
    else:
        av = lista.pop(len(lista) - 1)
        print(f'Item {av} foi removido da lista.')

lista = []
dicio = {'i': a, 'p': b, 'x': 'esta parte não importa'}
while True:
    while True:
        opção = input('''O que deseja fazer?
- [i] para inserir um nome na lista.
- [p] para excluir o primeiro item da lista.
- [x] para encerrar o programa.
''').lower().strip()
        if opção in dicio: break
        print('Opção inválida, tente novament')
    if opção == 'x': break
    # chama a função, não precisa pegar o retorno
    dicio[opção](lista)

After all, the functions are modifying the list that was passed and then returning it. But since it is the same list, does it need to return? It would make sense if the functions returned another list, but that’s not the case.

Note also that use str(input(...)) is redundant and unnecessary as input already returns a string, so the str in this case may be removed.

Another detail is that if you want to remove the first item from the list, it should be lista.pop(0). The way you did, you’re removing the last.

Browser other questions tagged

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