Multi-row python data entry
I would like to understand how to input various data (int, float, str...) per line but repeatedly (i.e. in multiple lines) so that I can save each given entry.
I understand that I will have to use a list to store each entry and, using split, I can input multiple data in the same row, but I get lost when it comes to doing this with multiple rows.
For example:
linha = input().split()
lista = []
for item in range(5):
x = int(linha[item])
lista.append(x)
print(lista)
This code gives me a line with several (integer) input data, I would like to repeat this process in as many rows as I want and with the various types of data I want. However, as a beginner, I still haven't gotten used to the syntax.
2 answers
The function input()
always returns a string, to work with other types of data we need to manipulate this string, so we go in parts.
Receive multiple values
We can solve this problem with different approaches, example:
Receiving all values at once.
We can receive a string with all the values separated by whitespace and use the str.split()
to "break" this string in a list of strings. Example:
linha = input("Digite os valores separados por espaço")
# ex.: '1 2 3 4 5'
valores = linha.split()
# ['1', '2', '3', '4', '5']
If you want to convert all values to integer you can use:
-
A
for
to iterate on the values, convert the value, and then add to the result list withlist.append()
.linha = input("Digite os valores separados por espaço") valores = [] for valor in linha.split(): valores.append(int(valor))
-
The function
map
to apply a function to all items in an iterable and create a new list with the result of the function for each position of the list.linha = input("Digite os valores separados por espaço") valores = linha.split() valores_convertidos = map(int, valores)
-
A list comprehension to iterate and convert all values:
linha = input("Digite os valores separados por espaço") valores = linha.split() valores_convertidos = [int(valor) for valor in valores]
Getting one value at a time
You can receive an indefinite number of inputs by using a loop and setting a stop criterion.
For example, receive integers while the user enters valid values:
valores = []
while True:
try:
linha = int(input("Digite um número:"))
except ValueError:
print("Valor inválido, saindo do loop")
break
valores.append(linha)
In the above code I am creating an "infinite" loop that will repeat itself while the conversion of user input to int
does not fail. When it fails it will launch a ValueError
running the break
inside except
Receiving a specific number of variables with pre-defined types
You can receive a specific number of inputs using the function range()
as you yourself posted in your question:
valores = []
for _ in range(5):
valor = input("Digite algo: ")
valores.append(valor)
The next step is to define the types of data we should receive. We could use integers or even strings to define data types.
Example:
# 0: int
# 1: str
# 2: float
tipos = [0, 1, 1, 0, 2]
valores = []
for tipo in tipos:
valor = input("Digite algo: ")
if tipo == 0:
valores.append(int(valor))
elif tipo == 1:
valores.append(valor) # já é string
elif tipo ==2:
valores.append(float(valor))
else:
print("Tipo inválido, nenhum valor adicionado")
I'm not going to go much deeper into the improvements that could be made in the above code as it's just a demonstration of how it could be done.
Instead of having multiple if
for each type you would like to have, you could use a list of functions that receive a string and return the type you want. In python, functions are "first class citizens" , that means you can pass them as parameters to other functions, assign them to variables, etc...
Then it is possible to do something like:
meu_int = int
valor = meu_int("10")
print(valor) # 10
Applying this concept, redoing the example and removing the if
would be:
tipos = [int, str, str, int, float]
valores = []
for tipo in tipos:
valor = input("Digite algo: ")
valores.append(tipo(valor))
code rolling no Repl.it
This way you are specifying that you want the user to enter 5 values, they being an integer, 2 strings, 1 integer, and 1 float, respectively. Not to mention that you can create your own functions or classes that receive a string as input and return an object of the type you want.
Conclusion
Since the subject is generic, it turned out that the answer got a little broad, but the important thing is that you understand that there are several approaches to the same problem and I hope I have given enough material for you to have a starting point for new studies and new questions.
Abuse and use of
try
texto = '''1
teste
1.5
balb
512
1,4'''
# Separa String por linhas e cria uma lista
lst = texto.split('\n')
lst_tratada = []
# Para cada valor que estiver na lista
for i in lst:
# Tenta registrar o valor como int e vai para o próximo laço, senão continua
try:
lst_tratada.append(int(i))
continue
except:
pass
# Tenta registrar o valor como float e vai para o próximo laço, senão continua
try:
lst_tratada.append(float(i))
continue
except:
# Se não conseguir nenhum dos dois, tratar como string
lst_tratada.append(i)
print(lst_tratada)
A simpler approach, from a method:
def var_parser(x):
try: # Tenta retornar x como inteiro
return int(x)
except: # Se não obtiver exito, continuar
pass
try: # Tenta retornar x como float
return float(x)
except: # Se não obtive exito, retornar x
return x
texto = '''1
teste
1.5
balb
512
1,4'''
lst = texto.split('\n')
lst_tratada = []
for i in lst:
lst_tratada.append(var_parser(i))
print(lst_tratada)