Déterminer si l'entier est entre deux autres entiers?

400

Comment puis-je déterminer si un entier donné se situe entre deux autres entiers (par exemple supérieur ou égal à 10000et inférieur ou égal à 30000)?

J'utilise 2.3 IDLE et ce que j'ai essayé jusqu'à présent ne fonctionne pas:

if number >= 10000 and number >= 30000:
    print ("you have to pay 5% taxes")
Enfant moyen
la source
20
Vérifiez vos opérateurs booléens, bien sûr, un nombre sera supérieur à 10000 s'il est supérieur à 30000. Regardez les petits détails et vous remarquerez bien plus d'erreurs.
Kaili
2
Les comparaisons peuvent être chaînées docs.python.org/2/reference/expressions.html#comparisons
theBuzzyCoder
7
Pls change> = 30000 à <= 30000
Badiboy

Réponses:

1048
if 10000 <= number <= 30000:
    pass
Paolo Moretti
la source
209
Python est tellement agréable :). Et pour être redondant: cela s'appelle la "comparaison d'intervalles".
Matt Montag
Quelle est la différence de vitesse entre cela et if number in range(10000, 30001)comme suggéré par une autre solution? De plus, est-il plus rapide ou plus lent lors de l'utilisation setau lieu de range?
Sung Cho
15
@MikeC Avec la comparaison d'intervalle numberest d'abord comparé 10000. S'il est inférieur, 10000l'expression est immédiatement court-circuitée et la deuxième comparaison n'est pas vérifiée. La complexité est O(1). in range(0, n)génère à la place la séquence entière de nombres puis l'itère. La complexité est O(n). La complexité de in set(range(0, n))est toujours O(n)parce que la construction d'un ensemble a une complexité temporelle de O(n) ics.uci.edu/~pattis/ICS-33/lectures/complexitypython.txt
Paolo Moretti
5
@MikeC Essayez de courir dans votre shell:> python -m timeit '10000 <= 10 <= 30000' > python -m timeit '10 in range(10000, 30001)' > python -m timeit '10 in set(range(10000, 30001))'
Paolo Moretti
3
ressemble à python3.5.2, la plage est ~ 10x plus lente que l'instruction if, avec une vitesse constante en ce qui concerne la valeur de vérification de la plage ... donc la différence la plus probable en raison de la surcharge de la fonction.
amohr
78
>>> r = range(1, 4)
>>> 1 in r
True
>>> 2 in r
True
>>> 3 in r
True
>>> 4 in r
False
>>> 5 in r
False
>>> 0 in r
False
Bohdan
la source
4
Wow, j'ai toujours pensé range(ou xrangeen python2) renvoyer un générateur, vous ne pouvez donc pas le tester à plusieurs reprises.
yegle
24
Il est important de garder à l'esprit que 4 in range(1,4)c'est faux. Il vaut donc mieux utiliser le 1 >= r <= 4car il évite les erreurs possibles des nouveaux arrivants
tripplet
50
1.5 in rdonne False, même en 3.4. Cette réponse n'est valable que pour les entiers.
jpmc26
9
@tripplet, vous avez fait la même erreur que l'OP !, ça devrait être1 <= r <= 4
John La Rooy
8
(1.) mauvaises performances (comme d'autres l'ont souligné, cette syntaxe semble bonne mais peut prendre beaucoup de temps à exécuter car ce sont des opérations O (n) vs les if a <= x <= b...) (2.) ne fonctionne pas pour les floattypes (3 .) le test de plage n'est pas inclusif ... donc de nombreux développeurs peuvent introduire des bogues car ils s'attendent à une plage inclusive
Trevor Boyd Smith
52

Votre opérateur est incorrect. Devrait l'être if number >= 10000 and number <= 30000:. De plus, Python a un raccourci pour ce genre de chose, if 10000 <= number <= 30000:.

Silas Ray
la source
3
... ce genre de chose est généralement appelé comparaison chaînée .
Wolf
30

Votre extrait de code,

if number >= 10000 and number >= 30000:
    print ("you have to pay 5% taxes")

vérifie en fait si le nombre est supérieur à 10000 et 30000.

En supposant que vous vouliez vérifier que le nombre est compris entre 10000 et 30000, vous pouvez utiliser la comparaison d'intervalle Python:

if 10000 <= number <= 30000:
    print ("you have to pay 5% taxes")

Cette fonctionnalité Python est décrite plus en détail dans la documentation Python .

Carl Ekerot
la source
9
if number >= 10000 and number <= 30000:
    print ("you have to pay 5% taxes")
Sandro Munda
la source
8

Le problème avec les comparaisons est qu'elles peuvent être difficiles à déboguer lorsque vous mettez un >=où il devrait y avoir un<=

#                             v---------- should be <
if number >= 10000 and number >= 30000:
    print ("you have to pay 5% taxes")

Python vous permet d' écrire simplement ce que vous voulez dire en mots

if number in xrange(10000, 30001): # ok you have to remember 30000 + 1 here :)

En Python3, vous devez utiliser à la rangeplace de xrange.

edit: Les gens semblent être plus préoccupés par les repères microbench et la façon dont les opérations de chaînage sont cool. Ma réponse concerne la programmation défensive (moins de surface d'attaque pour les bugs).

À la suite d'une réclamation dans les commentaires, j'ai ajouté le micro benchmark ici pour Python3.5.2

$ python3.5 -m timeit "5 in range(10000, 30000)"
1000000 loops, best of 3: 0.266 usec per loop
$ python3.5 -m timeit "10000 <= 5 < 30000"
10000000 loops, best of 3: 0.0327 usec per loop

Si vous êtes préoccupé par les performances, vous pouvez calculer la plage une fois

$ python3.5 -m timeit -s "R=range(10000, 30000)" "5 in R"
10000000 loops, best of 3: 0.0551 usec per loop
John La Rooy
la source
2
xrange est déprécié dans Python 3, malheureusement.
apraetor
1
@apraetor, oui utilisez range(10000, 30001)en Python3. Il ne crée pas de liste
John La Rooy
3
@JBChouinard, vous avez absolument tort. xrangeen Python2, ou rangeen Python3 ont des tests d'appartenance. Essayez-le vous-même si vous n'y croyez pas. <=est seulement plus efficace car il ne crée pas d'objet range. Dans les deux sens comme O (1). Le point est l'OP a essayé de le faire votre chemin et a fini avec un bug . Un code rapide erroné est pire.
John La Rooy
2
sur un i5, (i) python 3.5:% timeit 5 dans la plage (10000, 30000) 1000 boucles, le meilleur de 3: 451 µs par boucle. % timeit 10000 <= 5 <= 30000 10000000 boucles, meilleur de 3: 59,4 ns par boucle. c'est un facteur de plus de 7000
retour
1
@tback, S'il y avait une chance que ce soit 7 000 fois plus lent, je ne l'aurais pas suggéré. Vous pourriez peut-être essayer de relancer le test.
John La Rooy
8

Définissez la plage entre les nombres:

r = range(1,10)

Ensuite, utilisez-le:

if num in r:
    print("All right!")
joandiar91
la source
3
rangene compte pas la dernière valeur 10 dans votre cas. range(1,11)est correct, si vous devez comparer entre 1 et 10
ikbel benabdessamad
6

Il existe deux façons de comparer trois entiers et de vérifier si b est compris entre a et c :

if a < b < c:
    pass

et

if a < b and b < c:
    pass

Le premier semble plus lisible, mais le second s'exécute plus rapidement .

Comparons en utilisant dis.dis :

    >>> dis.dis('a < b and b < c')
  1           0 LOAD_NAME                0 (a)
              2 LOAD_NAME                1 (b)
              4 COMPARE_OP               0 (<)
              6 JUMP_IF_FALSE_OR_POP    14
              8 LOAD_NAME                1 (b)
             10 LOAD_NAME                2 (c)
             12 COMPARE_OP               0 (<)
        >>   14 RETURN_VALUE
>>> dis.dis('a < b < c')
  1           0 LOAD_NAME                0 (a)
              2 LOAD_NAME                1 (b)
              4 DUP_TOP
              6 ROT_THREE
              8 COMPARE_OP               0 (<)
             10 JUMP_IF_FALSE_OR_POP    18
             12 LOAD_NAME                2 (c)
             14 COMPARE_OP               0 (<)
             16 RETURN_VALUE
        >>   18 ROT_TWO
             20 POP_TOP
             22 RETURN_VALUE
>>>

et en utilisant timeit :

~$ python3 -m timeit "1 < 2 and 2 < 3"
10000000 loops, best of 3: 0.0366 usec per loop

~$ python3 -m timeit "1 < 2 < 3"
10000000 loops, best of 3: 0.0396 usec per loop

vous pouvez également utiliser la plage , comme suggéré précédemment, mais elle est beaucoup plus lente.

a_bridges
la source
0

Supposons qu'il y ait 3 entiers non négatifs: a, b, et c. Mathématiquement parlant, si nous voulons déterminer s'il cy a entre aet b, inclusivement, on peut utiliser cette formule:

(c - a) * (b - c)> = 0

ou en Python:

> print((c - a) * (b - c) >= 0)
True
Anastasiya-Romanova 秀
la source
C'est faux, prenez l'exemple simple a = 1, b = 2, c = 3 ba = 1 ca = 2 (ba) * (ca) = 1 * 2> = 0 True => 3 est compris entre 1 et 2
Richard Ardelean
Désolé pour l'erreur que j'ai faite. J'ai modifié ma réponse @RichardArdelean.
Anastasiya-Romanova
0

Vous souhaitez que la sortie imprime l'instruction donnée si et seulement si le nombre se situe entre 10 000 et 30 000.

Le code devrait être;

if number >= 10000 and number <= 30000:
    print("you have to pay 5% taxes")
Steffny Marif Bill
la source
3
Cette réponse a déjà été suggérée. Qu'est-ce que votre réponse ajoute à la question?
Jaideep Shekhar
0

La condition devrait être,

if number == 10000 and number <= 30000:
     print("5% tax payable")

la raison de l'utilisation number == 10000est que si la valeur du nombre est 50000 et si nous utilisons number >= 10000la condition passera, ce qui n'est pas ce que vous voulez.

Sadaf
la source
Cela échouera cependant pour 10001, par exemple. Il veut des nombres entre 10000 et 30000. Votre condition ne fonctionnera que pour le nombre == 10000.
guerreiro