Проверьте, есть ли два числа с плавающей точкой в ​​любом из данного списка диапазонов - PullRequest
0 голосов
/ 07 сентября 2018

У меня есть два числа с плавающей точкой no_a и no_b и пара диапазонов, представленных в виде двух списков элементов, содержащих нижнюю и верхнюю границу.

Я хочу проверить, находятся ли числа в одном из следующих диапазонов: [0, 0.33], [0.33, 0.66] или [0.66, 1.0].

Как я могу аккуратно написать это утверждение в коде Python?

Ответы [ 5 ]

0 голосов
/ 07 сентября 2018

Numpy с помощью вещания

import numpy as np

check = np.array([[0.4], [0.6]])
ranges = np.array([[0,0.33], [0.33,0.66], [0.66,1.0]])

((check >= ranges[:, 0]) & (check <= ranges[:, 1])).all(0).any()

True

Подробнее

check >= ranges[:, 0]

#  0.00  0.33  0.66     <
[[ True  True False]  # 0.4
 [ True  True False]] # 0.6

check <= ranges[:, 1]

#  0.33  0.66  1.00      >     
[[False  True  True]   # 0.4
 [False  True  True]]  # 0.6

a = (check >= ranges[:, 0]) & (check <= ranges[:, 1])
a

#  0.00  0.33  0.66      <
#  0.33  0.66  1.00      >     
[[False  True False]   # 0.4
 [False  True False]]  # 0.6

Чтобы оба значения check находились в одной паре диапазонов, все столбцы должны быть True

a.all(0)

[False  True False]

До тех пор, пока любой из них равен True

a.all(0).any()

True

Кукольный редукс

Однако мы могли бы преобразовать check и ranges для выполнения одной операции сравнения.

b = [1, -1]
(check.T * b >= ranges * b).all(1).any()

True
0 голосов
/ 07 сентября 2018
interval0 = (0.00, 0.33)
interval1 = (0.33, 0.66)
interval2 = (0.66, 1.00)

no_a = 0.1
no_b = 0.2

# checks for a single interval
def both_in_interval(no_a, no_b, interval):
    return (no_a >= interval[0] and no_a <= interval[1]) \
            and (no_b >= interval[0] and no_b <= interval[1])

# checks if it happens for 1 of them
print(any((both_in_interval(no_a, no_b, interval) for interval \
                            in [interval0, interval1, interval2])))
0 голосов
/ 07 сентября 2018

Взгляните на здесь .

Поместите ваши no_a и no_b в массив и проверьте, проходят ли все события ваш оператор.


Второе редактирование: Как уже указывалось, встроенная функция all превосходит версию numpy для этого небольшого набора данных, поэтому использование numpy было удалено:

ranges = [[0,0.33], [0.33,0.66], [0.66,1.0]]

for i in range(len(ranges)):
    if all([ranges[i][0] < no_a < ranges[i][1], 
            ranges[i][0] < no_b < ranges[i][1]]):
        print('Both values are in the interval of %s' %ranges[i])

, который выведет диапазон, в который попадают оба значения.

0 голосов
/ 07 сентября 2018

Как это:

RANGES = [[0,0.33], [0.33,0.66], [0.66,1.0]]


def check(no_a, no_b):
    for rng in RANGES:
        if rng[0] < no_a < rng[1] and rng[0] < no_b < rng[1]:
            return True
    else:
        return False


print(check(.1, .2))
print(check(.1, .4))

Вывод:

True
False

Или вот так:

no_a, no_b = .1, .2
print(any(rng[0] < no_a < rng[1] and rng[0] < no_b < rng[1] for rng in RANGES))
no_a, no_b = .1, .4
print(any(rng[0] < no_a < rng[1] and rng[0] < no_b < rng[1] for rng in RANGES))

Вывод:

True
False
0 голосов
/ 07 сентября 2018

Если вы просто хотите получить результат True или False, учтите следующее.

>>> a = 0.4
>>> b = 0.6
>>> 
>>> ranges = [[0,0.33], [0.33,0.66], [0.66,1.0]]
>>> 
>>> any(low <= a <= high and low <= b <= high for low, high in ranges)
True

Если у вас есть произвольное количество цифр для проверки (не только a и b), вы можете обобщить это так:

>>> numbers = [0.4, 0.6, 0.34]
>>> any(all(low <= x <= high for x in numbers) for low, high in ranges)
True
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...