Como posso ler entradas como números?

261

Por que são xe ystrings em vez de ints no código abaixo?

(Nota: no Python 2.x use raw_input(). No Python 3.x use input(). raw_input()Foi renomeado para input()no Python 3.x)

play = True

while play:

    x = input("Enter a number: ")
    y = input("Enter a number: ")

    print(x + y)
    print(x - y)
    print(x * y)
    print(x / y)
    print(x % y)

    if input("Play again? ") == "no":
        play = False
smci
fonte

Respostas:

313

TLDR

  • O Python 3 não avalia os dados recebidos com a inputfunção, mas a inputfunção do Python 2 faz (leia a próxima seção para entender a implicação).
  • O equivalente do Python 2 ao Python 3 inputé a raw_inputfunção.

Python 2.x

Havia duas funções para obter a entrada do usuário, chamadas inpute raw_input. A diferença entre eles é raw_inputque não avalia os dados e retorna como são, na forma de sequência. Porém, inputavaliará o que você inseriu e o resultado da avaliação será retornado. Por exemplo,

>>> import sys
>>> sys.version
'2.7.6 (default, Mar 22 2014, 22:59:56) \n[GCC 4.8.2]'
>>> data = input("Enter a number: ")
Enter a number: 5 + 17
>>> data, type(data)
(22, <type 'int'>)

Os dados 5 + 17são avaliados e o resultado é 22. Ao avaliar a expressão 5 + 17, ele detecta que você está adicionando dois números e, portanto, o resultado também será do mesmo inttipo. Portanto, a conversão do tipo é feita gratuitamente e 22é retornada como resultado inpute armazenada na datavariável Você pode considerar inputo raw_inputcomposto com uma evalchamada.

>>> data = eval(raw_input("Enter a number: "))
Enter a number: 5 + 17
>>> data, type(data)
(22, <type 'int'>)

Nota: você deve ter cuidado ao usar inputno Python 2.x. Expliquei por que devemos ter cuidado ao usá-lo, nesta resposta .

Mas, raw_inputnão avalia a entrada e retorna como é, como uma string.

>>> import sys
>>> sys.version
'2.7.6 (default, Mar 22 2014, 22:59:56) \n[GCC 4.8.2]'
>>> data = raw_input("Enter a number: ")
Enter a number: 5 + 17
>>> data, type(data)
('5 + 17', <type 'str'>)

Python 3.x

O Python 3.x inpute o Python 2.x raw_inputsão semelhantes e raw_inputnão estão disponíveis no Python 3.x.

>>> import sys
>>> sys.version
'3.4.0 (default, Apr 11 2014, 13:05:11) \n[GCC 4.8.2]'
>>> data = input("Enter a number: ")
Enter a number: 5 + 17
>>> data, type(data)
('5 + 17', <class 'str'>)

Solução

Para responder à sua pergunta, como o Python 3.x não avalia e converte o tipo de dados, você deve converter explicitamente para ints, com int, desta forma

x = int(input("Enter a number: "))
y = int(input("Enter a number: "))

Você pode aceitar números de qualquer base e convertê-los diretamente na base 10 com a intfunção

>>> data = int(input("Enter a number: "), 8)
Enter a number: 777
>>> data
511
>>> data = int(input("Enter a number: "), 16)
Enter a number: FFFF
>>> data
65535
>>> data = int(input("Enter a number: "), 2)
Enter a number: 10101010101
>>> data
1365

O segundo parâmetro informa qual é a base dos números inseridos e, em seguida, ele entende e converte internamente. Se os dados inseridos estiverem errados, será gerado a ValueError.

>>> data = int(input("Enter a number: "), 2)
Enter a number: 1234
Traceback (most recent call last):
  File "<input>", line 1, in <module>
ValueError: invalid literal for int() with base 2: '1234'

Para valores que podem ter um componente fracionário, o tipo seria, em floatvez de int:

x = float(input("Enter a number:"))

Além disso, seu programa pode ser alterado um pouco, como este

while True:
    ...
    ...
    if input("Play again? ") == "no":
        break

Você pode se livrar da playvariável usando breake while True.

thefourtheye
fonte
Existe alguma outra maneira, como uma função ou algo para que não precisemos converter para int no 3.x que não seja a conversão explícita para int?
Shreyan Mehta
O @ShreyanMehta evalfuncionaria, mas não faça isso a menos que você tenha razões urgentes.
thefourtheye
2
@ thefourtheye pelo menos use ast.literal_evalpara isso. Ele não tem as preocupações de segurança de eval.
espectros
4
Eu uso essas perguntas e respostas como um alvo idiota, mas talvez você possa adicionar um TDLR com a solução python 3, ou seja, int(input()... no topo? Python 2 está chegando ao fim dele é a vida e a informação python 3 está também enterrado IMO
Chris_Rands
A última parte sobre remover a reprodução como uma variável não é tão conveniente quanto a reprodução da variável torna o código mais compreensível. E dar sugestões de como o código pode mudar sem um motivo não é uma boa prática. Caso contrário, é uma resposta nice :)
OuuGiii
44

No Python 3.x, raw_inputfoi renomeado para inpute o Python 2.x inputfoi removido.

Isto significa que, assim como raw_input, inputem Python 3.x sempre retorna um objeto String.

Para corrigir o problema, é necessário transformar explicitamente essas entradas em números inteiros, colocando-as em int:

x = int(input("Enter a number: "))
y = int(input("Enter a number: "))
Georgy
fonte
27

Para vários números inteiros em uma única linha, mappode ser melhor.

arr = map(int, raw_input().split())

Se o número já for conhecido (como 2 inteiros), você poderá usar

num1, num2 = map(int, raw_input().split())
user1341043
fonte
16

input()(Python 3) e raw_input()(Python 2) sempre retornam strings. Converta o resultado em inteiro explicitamente com int().

x = int(input("Enter a number: "))
y = int(input("Enter a number: "))
Martijn Pieters
fonte
11

Várias perguntas requerem entrada para vários números inteiros em uma única linha. A melhor maneira é inserir toda a sequência de números em uma linha e depois dividi-los em números inteiros. Aqui está uma versão do Python 3:

a = []
p = input()
p = p.split()      
for i in p:
    a.append(int(i))

Também pode ser usada uma compreensão da lista

p = input().split("whatever the seperator is")

E para converter todas as entradas de string para int, fazemos o seguinte

x = [int(i) for i in p]
print(x, end=' ')

imprimirá os elementos da lista em uma linha reta.

gumboy
fonte
6

Converter em números inteiros:

my_number = int(input("enter the number"))

Da mesma forma para números de ponto flutuante:

my_decimalnumber = float(input("enter the number"))
Hemanth Savasere
fonte
4
n=int(input())
for i in range(n):
    n=input()
    n=int(n)
    arr1=list(map(int,input().split()))

o loop for deve executar 'n' número de vezes. o segundo 'n' é o comprimento da matriz. a última instrução mapeia os números inteiros para uma lista e recebe entrada em formato separado por espaço. você também pode retornar a matriz no final do loop for.

Ravi Tanwar
fonte
3

Eu encontrei um problema ao receber entrada inteira enquanto resolvia um problema no CodeChef , onde dois números inteiros - separados pelo espaço - deveriam ser lidos de uma linha.

Embora int(input())seja suficiente para um único número inteiro, não encontrei uma maneira direta de inserir dois números inteiros. Eu tentei isso:

num = input()
num1 = 0
num2 = 0

for i in range(len(num)):
    if num[i] == ' ':
        break

num1 = int(num[:i])
num2 = int(num[i+1:])

Agora eu uso num1 e num2 como números inteiros. Espero que isto ajude.

Aravind
fonte
Isso parece muito interessante. No entanto, não é idestruído quando o forloop é encerrado?
@hosch250Quando um loop é encerrado, o valor da variável de índice (aqui i) permanece. Eu tentei esta peça e funciona corretamente.
Aravind
1
Para esse tipo de manipulação de entrada, é possível num1, num2 = map(int, input().split())se você souber quantos números inteiros encontrará ou nums = list(map(int, input().split()))se não.
301_Moved_Permanently
3
def dbz():
    try:
        r = raw_input("Enter number:")
        if r.isdigit():
            i = int(raw_input("Enter divident:"))
            d = int(r)/i
            print "O/p is -:",d
        else:
            print "Not a number"
    except Exception ,e:
        print "Program halted incorrect data entered",type(e)
dbz()

Or 

num = input("Enter Number:")#"input" will accept only numbers
Sanyal
fonte
2

Enquanto no seu exemplo, int(input(...))faz o truque em qualquer caso, python-future's builtins.inputé digno de consideração, uma vez que torna-se seu código funciona tanto para Python 2 e 3 e comportamento padrão do desativa python2 de inputtentar ser 'inteligente' sobre o tipo de dados de entrada ( builtins.inputbasicamente apenas comporta-se como raw_input).

Tobias Kienzler
fonte