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")
Przeciętne dziecko
źródło
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
Paolo Moretti
źródło
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
Bohdan
źródło
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:.

Silas Ray
źródło
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 .

Carl Ekerot
źródło
9
if number >= 10000 and number <= 30000:
    print ("you have to pay 5% taxes")
Sandro Munda
źródło
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
John La Rooy
źródło
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!")
joandiar91
źródło
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.

a_bridges
źródło
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
Anastasiya-Romanova 秀
źródło
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")
Steffny Marif Bill
źródło
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.

Sadaf
źródło
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