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


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.