繁体   English   中英

寻找将字典键(基于值)划分为列表列表的最快方法,以便每个列表不超过某个阈值

[英]Looking for the fastest way to divide dictionary keys (based on values) into lists of list such that each list does not cross a certain threshold

我有一个 OrderedDictionary 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 ,如果我们 append '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)

它将 output 作为[[], ['1'], ['2'], ['3'], ['4', '5'], ['6']]给出。

在 O(n) 时间内寻找正确的解决方案。

谢谢!

第二个if应该额外检查l是否为空:

if curr_val + a[i] > threshold and l:

稍微不那么繁琐的代码:-

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))

根据运行总和,您可以通过将列表切换到 append 键来简化代码,以在整个结果和它的最后一个子列表之间。

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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM