在列表上分配值

时间:2018-02-19 00:38:05

标签: python list numpy

鉴于S = 25的数量且列表L = [10,20,30],我希望以下列方式将S分配给L: 输出 - > [10,15,0]

我编写了以下代码,完成了这项工作:

S = 25
l = [10,20,30]
res= []
b = True

for value in l:
    if b == True: 
        if S - value >0:
            res.append(value)
        else:
            res.append(S)
            b= False
        S -= value
    else:
        res.append(0)

是否有可能重写它,可能是一个单行? (允许numpy)

3 个答案:

答案 0 :(得分:2)

稍短且更易读:

def distribute(S, L):
    res = []
    for e in L:
        res.append(min(e, S))
        S = max(0, S-e)
    return res

虽然你可以使这个(或任何真正的)单行,但我不会强迫它。保持可读性更好。

您还可以使用等效的生成器函数:

def distribute(S, L):
    for e in L:
        yield min(e, S)
        S = max(0, S-e)

list(distribute(S, l))

答案 1 :(得分:1)

这是一种方式,但请不要因为他们是单行而加入单行。在可读性或性能方面,它们通常不是最好的方法。

from itertools import accumulate

S = 25
l = [10, 20, 30]

res = [i if j <= S else max(0, S-k) \
       for i, j, k in zip(l, accumulate(l), accumulate([0]+l))]

# [10, 15, 0]

答案 2 :(得分:0)

numpy

由于OP特别要求numpy,所以我们假设这是关于大型数组的。我认为OP主题中的distribute是一个关键字,因为这与PDF和CDF(https://en.wikipedia.org/wiki/Cumulative_distribution_function)之间的转换以及反之非常相似:

a = numpy.array([10, 20, 30])
c = a.cumsum()                   # [10, 30, 60]
b = c.clip(0, 25)                # [20, 25, 25]
numpy.ediff1d(b, to_begin=b[0])  # [10, 15, 0]