#python #algorithm #dictionary #data-structures #sliding-window
Вопрос:
У меня есть заказанный каталог a = {"1":800, "2":400, "3":600, "4":200, "5":100, "6":400}
Я хотел бы разделить ключи на список списков таким образом, чтобы общие значения каждого списка не превышали порогового значения (в данном случае 600), или если значение превышает пороговое значение, у него должен быть свой собственный список. Кроме того, мы проверяем только наличие следующей клавиши (например, в скользящем окне).
Приведенный выше словарь должен вернуться expected = [['1'], ['2'], ['3'], ['4', '5'], ['6']]
. Например, '1'
имеет свой собственный список, так как он превышает пороговое значение. '2'
имеет свой собственный список, так как значения '2' '3'
превышают пороговое значение. ['4', '5']
имеет суммарные значения до 600
, и если мы добавим '6'
, это превысит пороговое значение.
Вот что у меня есть до сих пор:
def check_result(a):
result = {}
curr_val = 0
threshold = 600
l =[]
result = []
for i in a.keys():
if curr_val >= threshold:
result.append(l)
l = []
curr_val = 0
if curr_val a[i] > threshold:
result.append(l)
l = [i]
curr_val = a[i]
else:
l.append(i)
curr_val = a[i]
result.append(l)
print(result)
Он выдает результат как [[], ['1'], ['2'], ['3'], ['4', '5'], ['6']]
.
Ищу правильное решение за O(n) времени.
Спасибо!
Комментарии:
1. обновил его, он должен был быть
l
2. Почему вы думаете, что ваше решение не является O(n)?
3. Подсписок должен быть непрерывным?
4. Да @DaniMesejo
5. @mkrieger мое решение прямо сейчас находится в O(n), но я не думаю, что оно на 100% правильное, также мне интересно, есть ли более чистый способ
Ответ №1:
У второго if
просто должна быть дополнительная проверка, которая l
не пуста:
if curr_val a[i] > threshold and l:
Ответ №2:
Немного менее громоздкий код:-
a = {"1": 800, "2": 400, "3": 600, "4": 200, "5": 100, "6": 400}
def check_result(d):
T = 600
result, e = [], []
s = 0
for k, v in d.items():
if e:
if s v > T:
result.append(e)
else:
e.append(k)
s = v
continue
e = [k]
s = v
if e:
result.append(e)
return result
print(check_result(a))
Ответ №3:
Основываясь на текущей сумме, вы можете оптимизировать код, переключая список для добавления ключей между целым результатом и его последним подсписком.
a = {"1":800, "2":400, "3":600, "4":200, "5":100, "6":400}
t = 600 # Treshold
r = [] # result, list of lists of keys
s = 0 # running sum
for k,v in a.items():
group,item,delta = (r[-1],k,v) if r and s v<=t else (r,[k],v-s)
group.append(item) # append to result or last sublist
s = delta # update running sum
print(r)
[['1'], ['2'], ['3'], ['4', '5'], ['6']]
Или этот несколько более короткий (но менее эффективный) вариант:
r,s = [],0 # result, running sum
for k,v in a.items():
r = [r.pop(-1) [k] if r and s v<=t else [k]]
s = v - s*(s v>t)