Sprawdź, czy liczba całkowita jest między dwiema innymi liczbami całkowitymi?


397

Jak ustalić, czy dana liczba całkowita znajduje się między dwiema innymi liczbami całkowitymi (np. Większa niż / równa 10000i mniejsza niż / równa 30000)?

Używam 2.3 IDLE i to, co do tej pory próbowałem, nie działa:

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

20
Sprawdź operatorów boolowskich, oczywiście liczba będzie większa niż 10000, jeśli będzie większa niż 30000. Spójrz na małe szczegóły, a dostrzeżesz znacznie więcej błędów.
— Kaili


6
Pls zmień> = 30000 na <= 30000
— Badiboy

Odpowiedzi:


1044
if 10000 <= number <= 30000:
    pass

207
Python jest taki miły :). I być zbędnym: nazywa się to „porównywaniem przedziałów”.
— Matt Montag

Jaka jest różnica prędkości między tym a if number in range(10000, 30001)sugerowanym przez inne rozwiązanie? Ponadto, czy jest szybszy czy wolniejszy, gdy używasz setzamiast range?
— Sung Cho

15
@MikeC Z porównaniem przedziałów numberjest najpierw porównywane 10000. Jeśli jest mniejszy niż, 10000wyrażenie jest natychmiast zwierane, a drugie porównanie nie jest sprawdzane. Złożoność jest O(1). in range(0, n)zamiast tego generuje całą sekwencję liczb, a następnie iteruje przez nią. Złożoność jest O(n). Złożoność in set(range(0, n))jest nadal, O(n)ponieważ budowanie zestawu ma złożoność czasową O(n) ics.uci.edu/~pattis/ICS-33/lectures/complexitypython.txt
— Paolo Moretti

5
@MikeC Spróbuj uruchomić się w swojej powłoce:> 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
wygląda na to, że w python3.5.2, zakres jest ~ 10x wolniejszy niż instrukcja if, ze stałą prędkości w odniesieniu do wartości kontrolnej zakresu ... więc najprawdopodobniej różnica wynika z narzutu funkcji.
— 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

4
Wow, zawsze myślałem range(lub xrangew python2) zwraca generator, więc nie można wielokrotnie testować na nim.
— yegle

24
Ważne jest, aby pamiętać, że 4 in range(1,4)jest to fałsz. Lepiej więc użyj tego, 1 >= r <= 4ponieważ pozwala uniknąć ewentualnych błędów przez nowych graczy
— tripplet

50
1.5 in rdaje False, nawet w 3.4. Ta odpowiedź jest dobra tylko dla liczb całkowitych.
— jpmc26

9
@tripplet, popełniłeś ten sam błąd co OP !, Powinno być1 <= r <= 4
— John La Rooy,

8
(1.) zła wydajność (jak zauważyli inni, ta składnia wygląda dobrze, ale jej wykonanie może zająć dużo czasu, ponieważ jest to operacja O (n) w porównaniu do if a <= x <= b...) (2.) nie działa dla floattypów (3) .) test zasięgu nie obejmuje ... tak wielu programistów może wprowadzić błędy, ponieważ spodziewają się włączenia zakresu
— Trevor Boyd Smith

52

Twój operator jest niepoprawny. Powinno być if number >= 10000 and number <= 30000:. Dodatkowo, Python posiada skrót do tego typu rzeczy, if 10000 <= number <= 30000:.


3
... tego typu rzeczy zwykle nazywane są porównywaniem łańcuchowym .
— Wolf

30

Twój fragment kodu,

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

faktycznie sprawdza, czy liczba jest większa niż zarówno 10000, jak i 30000.

Zakładając, że chcesz sprawdzić, czy liczba mieści się w zakresie od 10000 do 30000, możesz użyć porównania interwałów w języku Python:

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

Ta funkcja Pythona jest dokładniej opisana w dokumentacji Pythona .



8

Problem z porównaniami polega na tym, że mogą one być trudne do debugowania, gdy umieścisz tam, >=gdzie powinno być<=

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

Python pozwala ci pisać po prostu to, co masz na myśli

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

W Python3 musisz użyć rangezamiast xrange.

edytuj: Ludzie wydają się być bardziej zaniepokojeni śladami mikrobench i tym, jak fajne są operacje łańcuchowe. Moja odpowiedź dotyczy programowania defensywnego (mniejsza powierzchnia ataku dla błędów).

W wyniku twierdzenia w komentarzach dodałem tutaj test porównawczy mikro dla 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

Jeśli martwisz się wydajnością, możesz raz obliczyć zakres

$ python3.5 -m timeit -s "R=range(10000, 30000)" "5 in R"
10000000 loops, best of 3: 0.0551 usec per loop

2
Niestety, xrange jest przestarzały w Pythonie 3.
— apraetor

1
@apraetor, tak, użyj range(10000, 30001)w Python3. Nie tworzy listy
— John La Rooy

3
@JBChouinard, jesteś absolutnie niepoprawny. xrangew Python2 lub rangew Python3 mają testy członkostwa. Spróbuj sam, jeśli nie wierzysz. <=jest tylko bardziej wydajny, ponieważ nie tworzy obiektu zakresu. Oba sposoby jak O (1). Punkt jest OP została stara się zrobić to na swój sposób, a zakończył się z błędem . Nieprawidłowy szybki kod jest gorszy.
— John La Rooy,

2
na i5, (i) python 3.5:% timeit 5 w zakresie (10000, 30000) 1000 pętli, najlepiej 3: 451 µs na pętlę. % timeit 10000 <= 5 <= 30000 10000000 pętli, najlepiej 3: 59,4 ns na pętlę. to czynnik ponad 7000
— tback

1
@tback, Gdyby istniała szansa, że ​​byłaby 7000 razy wolniejsza, nie zasugerowałbym jej. Być może możesz spróbować ponownie uruchomić test.
— John La Rooy,

8

Zdefiniuj zakres między liczbami:

r = range(1,10)

Następnie użyj go:

if num in r:
    print("All right!")

3
rangenie liczy ostatniej wartości 10 w twoim przypadku. range(1,11)jest poprawne, jeśli chcesz porównać między 1 a 10
— ikbel benabdessamad

6

Istnieją dwa sposoby porównania trzech liczb całkowitych i sprawdzenia, czy b ma wartość między a i c :

if a < b < c:
    pass

i

if a < b and b < c:
    pass

Pierwszy wygląda na bardziej czytelny, ale drugi działa szybciej .

Porównajmy za pomocą 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
>>>

i używając 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

możesz także użyć zasięgu , jak sugerowano wcześniej, jednak jest on znacznie wolniejszy.


0

Załóżmy, że istnieją 3 nieujemne liczby całkowite: a, b, i c. Z matematycznego punktu widzenia, jeśli chcemy ustalić, czy cjest pomiędzy, ai bwłącznie, można użyć tej formuły:

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

lub w Pythonie:

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

To źle, weźmy prosty przykład a = 1, b = 2, c = 3 ba = 1 ca = 2 (ba) * (ca) = 1 * 2> = 0 Prawda => 3 jest między 1 a 2
— Richard Ardelean

Przepraszam za błąd, który popełniłem. Zredagowałem swoją odpowiedź @RichardArdelean.
— Anastasiya-Romanova 秀

0

Chcesz, aby wynik wypisał podaną instrukcję tylko wtedy, gdy liczba mieści się w przedziale od 10 000 do 30 000.

Kod powinien być;

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

3
Ta odpowiedź została już zasugerowana. Co twoja odpowiedź dodaje do pytania?
— Jaideep Shekhar

0

Warunkiem powinno być

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

powodem użycia number == 10000jest to, że jeśli wartość liczby wynosi 50000 i jeśli użyjemy, number >= 10000warunek przejdzie, co nie jest tym, czego chcesz.


Jednak nie powiedzie się to na przykład dla 10001. Chce liczb od 10000 do 30000. Twój stan będzie działał tylko dla liczby == 10000.
— guerreiro
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.