Comment lire les entrées sous forme de nombres?

261

Pourquoi xet les ychaînes au lieu des entiers dans le code ci-dessous?

(Note: l'utilisation de Python 2.x raw_input(). En Python 3.x utilisation input(). raw_input()A été renommé 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
la source

Réponses:

313

TLDR

  • Python 3 n'évalue pas les données reçues avec la inputfonction, mais la inputfonction de Python 2 le fait (lisez la section suivante pour comprendre l'implication).
  • L'équivalent de Python 2 de Python 3 inputest la raw_inputfonction.

Python 2.x

Il y avait deux fonctions pour obtenir une entrée utilisateur, appelées inputet raw_input. La différence entre eux est, raw_inputn'évalue pas les données et retourne tel quel, sous forme de chaîne. Mais, inputévaluera tout ce que vous avez entré et le résultat de l'évaluation sera retourné. Par exemple,

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

Les données 5 + 17sont évaluées et le résultat est 22. Lorsqu'il évalue l'expression 5 + 17, il détecte que vous ajoutez deux nombres et donc le résultat sera également du même inttype. Ainsi, la conversion de type est effectuée gratuitement et 22est retournée comme résultat de inputet stockée dans une datavariable. Vous pouvez penser inputcomme raw_inputcomposé avec un evalappel.

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

Remarque: vous devez être prudent lorsque vous utilisez inputen Python 2.x. J'ai expliqué pourquoi il fallait être prudent lors de son utilisation, dans cette réponse .

Mais, raw_inputn'évalue pas l'entrée et retourne telle quelle, sous forme de chaîne.

>>> 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.x inputet Python 2.x raw_inputsont similaires et raw_inputne sont pas disponibles dans 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'>)

Solution

Pour répondre à votre question, puisque Python 3.x n'évalue pas et ne convertit pas le type de données, vous devez convertir explicitement en ints, avec int, comme ceci

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

Vous pouvez accepter des nombres de n'importe quelle base et les convertir directement en base-10 avec la intfonction, comme ceci

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

Le deuxième paramètre indique quelle est la base des nombres entrés, puis en interne il le comprend et le convertit. Si les données saisies sont incorrectes, elles lanceront 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'

Pour les valeurs qui peuvent avoir une composante fractionnaire, le type serait floatplutôt que int:

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

En dehors de cela, votre programme peut être légèrement modifié, comme ceci

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

Vous pouvez vous débarrasser de la playvariable en utilisant breaket while True.

thefourtheye
la source
Existe-t-il un autre moyen, comme une fonction ou quelque chose pour que nous n'ayons pas besoin de convertir en int dans 3.x autre que de faire une conversion explicite en int ??
Shreyan Mehta
@ShreyanMehta evalfonctionnerait, mais n'y allez pas sauf si vous avez des raisons pressantes.
thefourtheye
2
@thefourtheye au moins utiliser ast.literal_evalpour cela. Il n'a pas les problèmes de sécurité de eval.
spectras
4
J'utilise ce Q&A comme cible dupe, mais peut-être pouvez-vous ajouter un TDLR avec la solution python 3, c'est- int(input()à- dire ... en haut? Python 2 approche de la fin de sa vie et les informations sur python 3 sont trop enterrées IMO
Chris_Rands
Le dernier élément concernant la suppression de la lecture en tant que variable n'est pas aussi pratique car la lecture variable rend le code plus compréhensible. Et donner des suggestions sur la façon dont le code pourrait changer sans raison n'est pas une bonne pratique. Sinon, c'est une bonne réponse :)
OuuGiii
44

Dans Python 3.x, a raw_inputété renommé inputet Python 2.x a inputété supprimé.

Cela signifie que, tout comme raw_input, inputen Python 3.x renvoie toujours un objet chaîne.

Pour résoudre le problème, vous devez explicitement transformer ces entrées en nombres entiers en les mettant int:

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

Pour plusieurs nombres entiers sur une seule ligne, cela mappourrait être mieux.

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

Si le nombre est déjà connu (comme 2 entiers), vous pouvez utiliser

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

input()(Python 3) et raw_input()(Python 2) renvoient toujours des chaînes. Convertissez le résultat en entier explicitement avec int().

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

Plusieurs questions nécessitent la saisie de plusieurs entiers sur une seule ligne. La meilleure façon est de saisir la chaîne entière de nombres sur une ligne, puis de les diviser en entiers. Voici une version Python 3:

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

Une compréhension de liste peut également être utilisée

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

Et pour convertir toutes les entrées de la chaîne en int, nous procédons comme suit

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

imprime les éléments de la liste en ligne droite.

gumboy
la source
6

Convertir en entiers:

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

De même pour les nombres à virgule flottante:

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

la boucle for doit être exécutée «n» nombre de fois. le second «n» est la longueur du tableau. la dernière instruction mappe les entiers à une liste et prend les entrées sous forme séparée par des espaces. vous pouvez également retourner le tableau à la fin de la boucle for.

ravi tanwar
la source
3

J'ai rencontré un problème de prise d'entrée entière lors de la résolution d'un problème sur CodeChef , où deux entiers - séparés par un espace - devraient être lus à partir d'une ligne.

Bien que cela int(input())soit suffisant pour un seul entier, je n'ai pas trouvé de moyen direct d'entrer deux entiers. J'ai essayé ceci:

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

Maintenant, j'utilise num1 et num2 comme entiers. J'espère que cela t'aides.

Aravind
la source
Cela semble très intéressant. Cependant, n'est-il pas idétruit à la forsortie de la boucle?
@hosch250Lorsqu'une boucle est quittée, la valeur de la variable d'index (ici i) reste. J'ai essayé cette pièce et elle fonctionne correctement.
Aravind
1
Pour ce type de manipulation d'entrée, vous pouvez le faire num1, num2 = map(int, input().split())si vous savez combien d'entiers vous rencontrerez ou nums = list(map(int, input().split()))si vous ne le faites pas.
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
la source
2

Alors que dans votre exemple, int(input(...))fait le tour dans tous les cas, python-futurel » builtins.inputEnvisage vaut depuis être sûr que vos œuvres de code pour Python 2 et 3 et le comportement par défaut désactive python2 d' inputessayer d'être « intelligent » sur le type de données d'entrée ( builtins.inputfondamentalement juste se comporte comme raw_input).

Tobias Kienzler
la source