How to display a list always sorted as new items are inserted

Asked

Viewed 128 times

2

I am trying to implement a list, in which, each number typed is inserted and counted in sequence, as in the example below:

lista = ['0']
while True:
    ean = input('digite aqui: ' )
    lista.append(ean)
    print map(lista)

I wish the comeback was...

digite aqui: 2                                                                                                                               
['1', '2']                                                                                                                            

digite aqui: 3                                                                                                                              
['1', '2', '3']                                                                                                                       

digite aqui: 4                                                                                                                               
['1', '2', '3', '4']

I would like it, regardless of what is inserted in "input", the program lists the elements in ascending order.

2 answers

3


If the list should save strings but you want to sort by numerical values, it is interesting to insert values only if they are numbers. For this you can use int to convert the string to number, and capture the ValueError if it is not (because if it is not a number, it makes no sense to try to sort by the numerical value).

lista = ['0']
while True:
    n = input('digite aqui: ')
    try:
        int(n) # tenta converter para número
        lista.append(n)
        print(sorted(lista, key=int)) # ordena a lista pelo valor numérico
    except ValueError:
        print('Não foi digitado um número')

I did so because it seems that you want the list to have strings (since in the output the numbers are in quotes).

But why did I do all this if a another answer seems to have worked? Well, you probably should only have tested with one-digit numbers. For sorting strings this way hides some traps. Ex:

lista = ['1', '2', '10']
lista.sort()
print(lista) # ['1', '10', '2']

Note that the 10 came before the 2. This is because strings are composed of characters, and even digits are considered characters, and the ordering takes into account their lexicographic order, not their numerical values (in this question has a more detailed explanation - although it is in Javascript, the concepts are basically the same and will help you understand why the 10 came before the 2 in ordination).

If you only test with one-digit numbers, the problem does not appear. But it is an important detail to look at.

Already doing key=int, i convert the strings to their respective numeric value, and this is considered in the sort. That is:

lista = ['1', '2', '10']
lista.sort(key=int)
print(lista) # ['1', '2', '10']

Another difference is that in the first example I used sorted, does not modify the original list. Already lista.sort modifies the list itself (i.e., depending on what you need, using one or the other makes a difference).


Although I don’t think it’s very efficient to sort the list all the time. If you always need to show it in an orderly fashion, an alternative is to ensure that the elements are always in order.

For this we can use the module bisect, which has methods - such as the insort - to insert in an orderly manner into the list:

from bisect import insort

lista = [0]
while True:
    try:
        insort(lista, int(input('digite aqui: ')))
        print(lista)
    except ValueError:
        print('Não foi digitado um número')

Thus, the elements will always be in order, simply print the list directly.

Another difference is that the list now contains numbers instead of strings (i.e., they are printed without the quotes). If you really want them to be printed as strings, you can convert them when printing print(list(map(str, lista))) instead of just print(lista).

1

Note that in this issue you will have to implement a laço de repetição.

Regardless of the loop you use, you will need a "flag" stop. This flag will stop typing possible subsequent values. Because, you cannot simply insert indefinidamente values in the list. In addition, in each iteration the list should be displayed in the best possible way, i.e. "ordenada".

Faced with these issues, I developed the following code...

# Este programa solicita uma flag para ser executado ou encerrado. Se a
# flag for "N" ou "n", o programa será encerrado. Se a flag for "S" ou "s",
# o programa solicitará um número, depois insere o número de forma ordenada
# na lista, depois exibe a lista atualizada e ordenada, em seguida, reinicia
# o loop que, de acordo com a decisão do usuário, poderá continuar o processo ou
# encerra-lo.

from bisect import insort
from time import sleep

cont = 0
lista = list()
continuar = True
while continuar == True:

    cont += 1
    if cont == 1:
        palavra = 'algum'
    else:
        palavra = 'outro'

    # Solicita uma flag para continuar a execução ou encerra-lo.
    resposta = str(input(f'Desejas inserir {palavra} número? [S/N] ')).strip()
    while resposta not in 'SsNn':
        print('\033[31mValor INVÁLIDO! Digite apenas "S" ou "N"!\033[m')
        resposta = str(input(f'Desejas inserir {palavra} número? [S/N] ')).strip()

    # Caso a flag inserida seja "S" ou "s", inicia-se a inserção de valores na lista.
    if (resposta == 'S') or (resposta == 's'):
        # Captura e trata o valor digitado:
        while True:
            try:
                v = int(input(f'Digite o {cont}º número: '))
                break
            except:
                print('\033[31mValor INVÁLIDO! Digite apenas números inteiros!\033[m')

        # Inseri o valor inteiro de forma ordenada na lista.
        insort(lista, v)

        # Exibi a lista atualizada e ordenada a cada interação do loop.
        print(f'\033[32mLista atualizada e ordenada: {lista}\033[m')

        # Reinicia o Loop.
        continuar = True

    # Caso a flag inserida seja "N" ou "n", encerra-se a execução do programa.
    else:
        print('\033[31mEncerrando o programa!')
        # Animação da barra de progresso de encerramento.
        for c in range(1, 48):
            print(chr(46), end='')
            sleep(0.1)
        print()

        continuar = False
        break

Note the functioning of the algorithm in Repl.it

Browser other questions tagged

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