¿Cómo puedo leer entradas como números?

261

¿Por qué son xy ycadenas en lugar de ints en el siguiente código?

(Nota: en Python 2.x uso raw_input(). En Python 3.x uso input(). raw_input()Se renombró input()en 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
fuente

Respuestas:

313

TLDR

  • Python 3 no evalúa los datos recibidos con la inputfunción, pero la inputfunción de Python 2 sí (lea la siguiente sección para comprender la implicación).
  • El equivalente de Python 2 a Python 3 inputes la raw_inputfunción.

Python 2.x

Había dos funciones para obtener la entrada del usuario, llamadas inputy raw_input. La diferencia entre ellos es, raw_inputno evalúa los datos y regresa como es, en forma de cadena. Pero, inputevaluará lo que haya ingresado y se devolverá el resultado de la evaluación. Por ejemplo,

>>> 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'>)

Los datos 5 + 17se evalúan y el resultado es 22. Cuando evalúa la expresión 5 + 17, detecta que está agregando dos números y, por lo tanto, el resultado también será del mismo inttipo. Por lo tanto, la conversión de tipo se realiza de forma gratuita y 22se devuelve como resultado de inputy almacenada en datavariable. Puedes pensar inputcomo el raw_inputcompuesto con una evalllamada.

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

Nota: debe tener cuidado cuando esté usando inputPython 2.x. Le expliqué por qué uno debe tener cuidado al usarlo, en esta respuesta .

Pero, raw_inputno evalúa la entrada y regresa como es, como una cadena.

>>> 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

Python 3.xy inputPython 2.x raw_inputson similares y raw_inputno están disponibles en 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'>)

Solución

Para responder a su pregunta, dado que Python 3.x no evalúa ni convierte el tipo de datos, debe convertir explícitamente a ints, con int, de esta manera

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

Puede aceptar números de cualquier base y convertirlos directamente a base-10 con la intfunción, como esta

>>> 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

El segundo parámetro dice cuál es la base de los números ingresados ​​y luego internamente lo comprende y lo convierte. Si los datos ingresados ​​son incorrectos, arrojará un 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 pueden tener un componente fraccionario, el tipo sería floatmás que int:

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

Aparte de eso, su programa se puede cambiar un poco, así

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

Puede deshacerse de la playvariable usando breaky while True.

thefourtheye
fuente
¿Hay alguna otra manera, como una función o algo así, para que no necesitemos convertir a int en 3.x aparte de hacer una conversión explícita a int?
Shreyan Mehta
@ShreyanMehta evalfuncionaría, pero no lo hagas a menos que tengas razones apremiantes.
thefourtheye
2
@thefourtheye al menos lo utilizo ast.literal_evalpara eso. No tiene las preocupaciones de seguridad de eval.
espectras
44
Utilizo estas preguntas y respuestas como un objetivo engañado, pero tal vez pueda agregar un TDLR con la solución python 3, es decir int(input()... ¿en la parte superior? Python 2 está llegando al final de su vida útil y la información de Python 3 está demasiado enterrada IMO
Chris_Rands
La última parte sobre eliminar la reproducción como variable no es tan conveniente ya que la reproducción variable hace que el código sea más comprensible. Y dar sugerencias sobre cómo podría cambiar el código sin una razón no es una buena práctica. De lo contrario, es una buena respuesta :)
OuuGiii
44

En Python 3.x, raw_inputse le cambió el nombre inputy inputse eliminó Python 2.x.

Esto significa que, al igual que raw_input, inputen Python 3.x siempre devuelve un objeto de cadena.

Para solucionar el problema, debe hacer explícitamente esas entradas en números enteros poniéndolos en int:

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

Para un entero múltiple en una sola línea, mappodría ser mejor.

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

Si el número ya se conoce (como 2 enteros), puede usar

num1, num2 = map(int, raw_input().split())
usuario1341043
fuente
16

input()(Python 3) y raw_input()(Python 2) siempre devuelven cadenas. Convierta el resultado a entero explícitamente con int().

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

Varias preguntas requieren la entrada de varios enteros en una sola línea. La mejor manera es ingresar toda la cadena de números una línea y luego dividirlos en enteros. Aquí hay una versión de Python 3:

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

También se puede utilizar una lista de comprensión

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

Y para convertir todas las entradas de cadena a int hacemos lo siguiente

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

imprimirá los elementos de la lista en línea recta.

Gumboy
fuente
6

Convierte a enteros:

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

De manera similar para números de coma flotante:

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

el ciclo for se ejecutará 'n' número de veces. la segunda 'n' es la longitud de la matriz. la última declaración asigna los enteros a una lista y toma la entrada en forma separada por espacios. También puede devolver la matriz al final del ciclo for.

ravi tanwar
fuente
3

Encontré un problema al tomar una entrada entera al resolver un problema en CodeChef , donde dos enteros, separados por espacio, deberían leerse desde una línea.

Si bien int(input())es suficiente para un solo entero, no encontré una forma directa de ingresar dos enteros. Intenté esto:

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:])

Ahora uso num1 y num2 como enteros. Espero que esto ayude.

Aravind
fuente
Esto se ve muy interesante. Sin embargo, ¿no se idestruye cuando forse sale del bucle?
@hosch250Cuando se sale de un bucle, el valor de la variable de índice (aquí i) permanece. Probé esta pieza y funciona correctamente.
Aravind
1
Para este tipo de manipulación de entrada, puede hacerlo num1, num2 = map(int, input().split())si sabe cuántos enteros encontrará o nums = list(map(int, input().split()))si no.
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
fuente
2

Mientras que en su ejemplo, int(input(...))hace el truco, en cualquier caso, python-future's builtins.inputvale la pena considerar, ya que asegura que su código funciona tanto para Python 2 y 3 y el comportamiento predeterminado desactiva de python2 de inputtratar de ser 'inteligente' sobre el tipo de datos de entrada ( builtins.inputbásicamente sólo se comporta como raw_input)

Tobias Kienzler
fuente