#python #list #bisect
#python #Список #разделить пополам
Вопрос:
У меня есть два списка
a = [1, 4, 12]
b = [2, 13]
Я хочу знать, находятся ли значения в list b
между двумя значениями в list a
Итак, в этом случае 2 будет находиться между 1 и 4. 13 не будет находиться между никакими числами.
Я пробовал bisect
function, но не смог заставить его работать. Я смог использовать его с одним значением и списком, но не с двумя списками.
Комментарии:
1. В приведенном выше случае вы хотите, чтобы вывод был [True, False]
2. Между любыми двумя числами или между числами, которые следуют друг за другом или непосредственно друг за другом? Отсортирован ли первый список? И вы ищете только да / нет или фактические числа и / или их позицию в списке? Должны ли все значения in
b
находиться между одинаковыми числами изa
, или они независимы?3. @SidKwakkel да, True, False будет работать
4. @tobias_k два списка независимы — между двумя числами не может быть никакого значения. Кроме того, предположим, что два списка отсортированы.
5. Кроме того, означает ли «между», что числа должны быть строго меньше и меньше, чем те, которые они «между»? А как насчет границ? Будет
1
4
ли и12
быть «между» любыми числамиa
?
Ответ №1:
Возможно, есть какая-то тонкость, которую я не понимаю, но, если я не ошибаюсь, вам нужно только проверить, находятся ли элементы между min
и max
from a
. Это не зависит от того, отсортированы ли элементы в a
, или значения из b
должны быть между последовательными значениями из a
. Пока они находятся между min
и max
, в этих значениях должен a
быть «сегмент».
>>> a = [1, 4, 12]
>>> b = [2, 13]
>>> n, m = min(a), max(a)
>>> [n < x < m for x in b]
[True, False]
Это, конечно, только в том случае, если (а) вам не нужно, какие числа они находятся между ними, и (б) если не все значения в b
должны быть в одном и том же интервале.
Если вы считаете, что я что-то пропустил, пожалуйста, прокомментируйте.
Комментарии:
1. подождите, это правильно! как мы это пропустили. Кроме
(a)
того, указанный вами пункт на самом деле не является недостатком. Должно работать в[x for x in b if n < x < m]
любом случае.2. Одно из возможных предостережений: если «между» действительно означает
n < x < m
, то может не быть никакого интервала, в котором числаb
находятся «между», если списокa
«плотный», например3
, не находится между какими-либо числами[1,2,3,4,5]
.3. я предполагаю, что a и be никогда не будут иметь одинаковое число. если 3 находится в списке A, то B никогда не будет содержать 3
Ответ №2:
Это действительно зависит от того, что вы хотите, чтобы оно вернуло. Я написал код, который вернет первый найденный шаблон, но с некоторыми изменениями, я уверен, будет нетрудно вернуть все комбинации.
def get_between(a, b):
a, b = sorted(a), sorted(b)
for b_value in b:
smaller = None
greater = None
for a_value in a:
if b_value > a_value:
smaller = a_value
elif b_value < a_value:
greater = a_value
if smaller and greater:
return f"{b_value} is between {smaller} and {greater}"
return "There is no such combination"
a = [1, 4, 12]
b = [2, 13]
print(get_between(a, b))
Вывод в этом случае будет 2 is between 1 and 4
, но вы можете адаптировать возвращаемое значение к тому, что вы хотите.
Ответ №3:
Вы можете сохранить два запущенных индекса, чтобы получить список всех элементов, которые находятся между значениями:
def get_between(arr1, arr2):
# first sort the arrays
arr1 = sorted(arr1)
arr2 = sorted(arr2)
# keep two indices into them
i1 = 0
i2 = 0
# keep track of the values between two values
ret = []
while i1 < len(arr1) - 1 and i2 < len(arr2):
# we're too small to be between a value
# so we should increase the second index
if arr2[i2] < arr1[i1]:
i2 = 1
# we're too large to be between a value
# so we should increase the first index
elif arr2[i2] > arr1[i1 1]:
i1 = 1
# we are between a value
# so we should append to the return array
# and move on to the next element
else:
ret.append(arr2[i2])
i2 = 1
return ret
get_between([1, 4, 12], [2, 8, 13]) # [2, 8]
Ответ №4:
Если вы не очень заботитесь о производительности, вот решение pythonic-
def betwn(rangelist, valuelist):
# Get list of all ranges between each consecutive number of rangelist
rgs = [range(rangelist[n], rangelist[n 1]) for n in range(len(rangelist) - 1)]
# A function to check whether a given element exists between 2 consecutive numbers of rangelist
verifyfunc = lambda e: any(e in r for r in rgs)
# Return the qualifying elements from valuelist
return [e for e in valuelist if verifyfunc(e)]
Вывод
>>> betwn([1, 4, 12], [2, 13])
[2]