Визначте, чи ціле число між двома іншими цілими числами?


397

Як визначити, чи є ціле ціле число між двома іншими цілими числами (наприклад, більше / рівне 10000та менше / рівне 30000)?

Я використовую 2.3 IDLE, і те, що я намагався до цього часу, не працює:

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

20
Перевірте своїх булевих операторів, звичайно, число буде більше 10000, якщо воно більше 30000. Подивіться на дрібниці, і ви зберетеся набагато більше помилок.
Каїлі

2
Порівняння можна прикувати docs.python.org/2/reference/expressions.html#comparisons
theBuzzyCoder

6
Змініть Pls> = 30000 до <= 30000
Бадібой

Відповіді:


1044
if 10000 <= number <= 30000:
    pass

207
Пітон такий приємний :). І, щоб бути зайвим: це називається "інтервальним порівнянням".
Метт Монтаг

Яка різниця швидкостей між цим та if number in range(10000, 30001)запропонованим іншим рішенням? Крім того, це швидше чи повільніше при використанні setзамість range?
Sung Cho

15
@MikeC З інтервалом порівняння numberспочатку порівнюється проти 10000. Якщо менше, ніж 10000вираз негайно замикається, а друге порівняння не перевіряється. Складність така O(1). in range(0, n)натомість генерує всю послідовність чисел, а потім повторює через неї. Складність така O(n). Складність in set(range(0, n))все ще полягає в O(n)тому, що складання набору має часову складність O(n) ics.uci.edu/~pattis/ICS-33/lectures/complexitypython.txt
Paolo Moretti

5
@MikeC Спробуйте запустити свою оболонку:> 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
виглядає, як у python3.5.2, діапазон на ~ 10 разів повільніше, ніж оператор if, зі сталою швидкістю щодо контрольної величини діапазону ... таким чином, найімовірніше, різниця через функцію накладних витрат.
амор

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
Нічого собі, я завжди думав range(або xrangeв python2) повертає генератор, таким чином ви не можете повторно перевірити його.
yegle

24
Важливо так пам’ятати, що 4 in range(1,4)це Неправда. Тож краще скористайтеся тим 1 >= r <= 4, що це дозволяє уникнути можливих помилок новачків
триплет

50
1.5 in rдає False, навіть у 3,4. Ця відповідь корисна лише для цілих чисел.
jpmc26

9
@tripplet, ви зробили ту саму помилку, що й ОП !, це повинно бути1 <= r <= 4
Джон Ла Рой

8
(1.) погана ефективність (як зазначають інші, цей синтаксис виглядає добре, але виконання може зайняти тривалий час, тому що це операції O (n) проти if a <= x <= b...) (2.) не працює для floatтипів (3 .) тест на діапазон не включає ... так що багато розробників можуть вводити помилки, тому що вони очікують включення діапазону
Тревор Бойд Сміт


30

Ваш фрагмент коду,

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

насправді перевіряє, чи число більше, ніж 10000 та 30000.

Припускаючи, що ви хочете перевірити, що число знаходиться в діапазоні 10000 - 30000, ви можете використовувати порівняння інтервалу Python:

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

Ця функція Python далі описана в документації на Python .



8

Проблема зі порівняннями полягає в тому, що вони можуть бути важкими для налагодження, коли ви ставите місце, >=де повинно бути<=

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

Python дозволяє вам просто писати те, що ви маєте на увазі словами

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

У Python3 вам потрібно використовувати rangeзамість xrange.

редагувати: Люди, здається, більше стурбовані мітками мікробенка та наскільки крутими ланцюговими операціями. Моя відповідь стосується оборонного (менше атаки для помилок) програмування.

У результаті претензії в коментарях я тут додав мікро-орієнтир для 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

Якщо ви турбуєтесь про ефективність, ви можете обчислити діапазон один раз

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

2
На жаль, у Python 3 застарілий xrange застарілий.
apraetor

1
@apraetor, так, використовуйте range(10000, 30001)в Python3. Це не створює список
Джон Ла Рой

3
@JBChouinard, ви абсолютно неправильні. xrangeв Python2 або rangeв Python3 мають тести на членство. Спробуйте самі, якщо не вірите. <=є лише більш ефективним, оскільки не створює об’єкт діапазону. Обидва способи, як O (1). Справа в тому , що ОП був намагається зробити це по- своєму і в кінцевому підсумку з помилкою . Швидкий код, який неправильний - гірше.
Джон Ла Рой

2
на i5, (i) пітон 3,5:% timeit 5 в діапазоні (10000, 30000) 1000 петель, найкраще 3: 451 мкс на цикл. % timeit 10000 <= 5 <= 30000 10000000 петель, найкраще 3: 59,4 нс на цикл. це коефіцієнт понад 7000
tback

1
@tback, Якби шанс був 7000 разів повільніше, я б не запропонував цього. Можливо, ви можете спробувати запустити тест ще раз.
John La Rooy

8

Визначте діапазон між числами:

r = range(1,10)

Потім використовуйте його:

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

3
rangeне враховує останнє значення 10 у вашому випадку. range(1,11)правильно, якщо вам потрібно порівняти між 1 та 10
ikbel benabdessamad

6

Є два способи порівняння трьох цілих чисел та перевірки, чи b є між a і c :

if a < b < c:
    pass

і

if a < b and b < c:
    pass

Перший виглядає як читабельніший, але другий працює швидше .

Давайте порівняємо, використовуючи 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
>>>

та використовуючи 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

Крім того, ви можете використовувати дальність , як було запропоновано раніше, однак це набагато повільніше.


0

Припустимо , що існує 3 невід'ємні цілі числа: a, b, і c. Математично кажучи, якщо ми хочемо визначити, чи cє між, aі bвключно, можна використовувати цю формулу:

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

або в Python:

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

Це неправильно, візьмемо простий приклад a = 1, b = 2, c = 3 ba = 1 ca = 2 (ba) * (ca) = 1 * 2> = 0 Істинно => 3 між 1 і 2
Річард Арделея

Вибачте за допущену помилку. Я відредагував свою відповідь @RichardArdelean.
Анастасія-Романова 秀

0

Ви хочете, щоб вихід друкував дане висловлення тоді і тільки тоді, коли число падає між 10 000 і 30 000.

Кодекс повинен бути;

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

3
Цю відповідь уже запропоновано. Що ваша відповідь додає до питання?
Джайдеп Шехар

0

Умова повинна бути,

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

Причина використання number == 10000полягає в тому, що якщо значення числа 50000, і якщо ми використовуємо number >= 10000умову, це перейде, що не є тим, що ви хочете.


Наприклад, для 10001 цього не вдасться. Він хоче цифри від 10000 до 30000. Ваш стан працюватиме лише для числа == 10000.
Геррейро
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.