Вы можете использовать collections.defaultdict
и bisect
модуля здесь:
Поскольку диапазоны являются непрерывным, так что было бы лучше, чтобы преобразовать список b
в нечто вроде первого:
[10, 40, 60, 90, 100]
Преимущества это значит, что теперь мы можем использовать модуль bisect
, чтобы найти индекс, в котором могут находиться элементы из списка. Например, 50 будет находиться между 40 и 60, поэтому bisect.bisect_right
вернет 2 в этом случае. Нет, мы можем использовать этот 2 как ключ и сохраняем список как его ценность. Таким образом, мы можем сгруппировать эти элементы на основе индекса, возвращаемого с bisect.bisect_right
.
L_b = 2* len(b)
L_a = len(a)
L_b1 = len(b1)
Общая сложность будет: max (L_b log L_b , L_a log L_b1 )
>>> import bisect
>>> from collections import defaultdict
>>> b=[(10,40),(40,60),(60,90),(90,100)]
>>> b1 = sorted(set(z for x in b for z in x))
>>> b1
[10, 40, 60, 90, 100]
>>> dic = defaultdict(list)
for x,y in a:
#Now find the index where the value from the list can fit in the
#b1 list, bisect uses binary search so this is an O(log n) step.
# use this returned index as key and append the list to that key.
ind = bisect.bisect_right(b1,int(x))
dic[ind].append([x,y])
...
>>> dic.values()
[[['10', 'name_1']], [['50', 'name_2'], ['40', 'name_3']], [['80', 'name_N']]]
Как dicts не имеет какого-либо конкретного использования порядка сортировки, чтобы получить отсортированный вывод:
>>> [dic[k] for k in sorted(dic)]
[[['10', 'name_1']], [['50', 'name_2'], ['40', 'name_3']], [['80', 'name_N']]]
Диапазоны в 'b' всегда будут непрерывными? –
Да, они есть, а 'a' упорядочивается _name_, а не первым полем элемента – fady
. Bisect может быть полезной здесь – dansalmo