#python #list
#python #Список
Вопрос:
У меня есть два списка:
a = [1,3,6,10,20]
b = [2,4,9,12,15,22,24,25]
Теперь я хотел бы создать новый список, содержащий пары из двух предыдущих списков. Пары определяются как таковые:
- Левое значение [l,..] :
a[i]
- Правый [.., r]: наибольшее число
b
междуa[i]
ними, иa[i 1]
еслиa[i 1]
существует, else просто больше, чемa[i]
, еслиa[i]
существует, else просто больше, чемa[-1]
с0 < i < max(len(a),len(b))
Результат будет выглядеть так:
pair = [[1,2],[3,4],[6,9],[10,15],[20,25]]
Кто-нибудь знает, как это сделать?
Это то, что я сделал до сих пор:
a = [1,3,6,10,20]
b = [2,4,9,12,15,22,24,25]
pairs = []
counter = 0
for i in range(max(len(a),len(b))):
try:
# get a[i]
ai = a[i]
except:
ai = a[-1]
try:
# get a[i 1]
ai1 = a[i 1]
except:
ai1 = b[-1] 1
temp = []
for bi in b:
if ai < bi and bi < ai1:
temp.append(bi)
# Avoid adding the last element of b again and again until i = len(b)
if max(temp) == b[-1]:
counter = counter 1
if counter <= 1:
print(max(temp))
pairs.append([ai,max(temp)])
Это нормально, поскольку он выполняет свою работу, но мне было интересно, есть ли лучший, более эффективный способ сделать это?
Комментарии:
1. Для начала удалите все эти блоки try / except . Я предполагаю, что у вас есть те, которые там для обработки граничных случаев границ массива. Но на практике все, что это сделает, это скроет реальные ошибки в вашем коде.
2. Отсортированы ли списки?
3. @FranciscoCouzo Да, это так !
4. @selbie Да. Знаете ли вы способ, как лучше обрабатывать крайние случаи?
5. Начните с написания кода без учета крайних случаев. Затем определите крайние случаи (конец списка, пустой список, элемент не найден и т. Д.) И исправьте с помощью условных операторов (
if
иelse
).
Ответ №1:
Вы можете выполнить двоичный поиск, поскольку массивы отсортированы, вам не нужно искать a[i] < b[j]
, только для a[i 1] > b[j]
(этот код вернет недопустимые результаты, если в них нет b
таких элементов, что a[i] < b < a[b 1]
):
import bisect
def pairs(a, b):
for (a1, a2) in zip(a, a[1:]):
yield a1, b[bisect.bisect_left(b, a2) - 1]
yield a[-1], b[-1]
print(list(pairs([1,3,6,10,20], [2,4,9,12,15,22,24,25])))
[(1, 2), (3, 4), (6, 9), (10, 15), (20, 25)]
Комментарии:
1. Это можно было бы немного оптимизировать, передав
lo
аргументbisect_left
, чтобы он начал поиск с последнего места, где он что-то нашел
Ответ №2:
Вот еще один способ сделать это:
a = [1,3,6,10,20]
b = [2,4,9,12,15,22,24,25]
merged = sorted(a b, reverse=True)
mask = [(False, True)[x in a] for x in merged]
flag = True
good = []
for m, n in zip(mask, merged):
if m is flag:
continue
else:
good.append(n)
flag = not flag
pairs = list(zip(good[1::2], good[::2]))[::-1]
pairs
>>> [(1, 2), (3, 4), (6, 9), (10, 15), (20, 25)]