均衡列表中的元素

时间:2015-02-14 05:40:57

标签: python

我正在尝试均衡元素列表。简而言之,我有一个x长度的数组,每个元素y的范围是0到100000.为了完成我想要做的事情,列表中的所有元素必须相互相等(尽可能)。

以下是我当前函数的一些示例输出:

>>> equal([1, 4, 1])
[2, 2, 2]
>>> equal([2, 4, 5, 9])
[5, 5, 5, 5]
>>> equal([2, 2])
[2, 2]
>>> equal([1, 2, 3, 4, 5, 6, 7, 8, 9])
[5, 5, 5, 5, 5, 5, 5, 5, 5]
>>> equal([2, 4, 6, 8, 10, 20, 30, 40])
[15, 15, 15, 15, 15, 15, 15, 15]
>>> equal([343, 452, 948, 283, 394, 238, 283, 984, 236, 847, 203])
[474, 474, 474, 474, 474, 474, 474, 474, 473, 473, 473]

相关代码:

def equal(l):
    # The number of times we distribute to the new loop
    loops = reduce(lambda x, y: x + y, l)

    # Initializes a new list as such: [0, 0, 0 .. len(l)]
    nl = [0 for x in range(len(l))]

    # Counts how far we've iterated into our new list
    x = 0
    for i in range(loops):
        # Add 1 to this element and move on to the next element in the list
        nl[x] += 1
        x += 1

        # Ensure we don't traverse past the end of the list
        if x > len(nl) - 1:
            x = 0

    return nl

现在的问题是,一旦你进入非常大的列表(100多个具有大值的元素),它就变得非常慢。我在这里找不到一些可以提高效率的成语吗?

2 个答案:

答案 0 :(得分:2)

所有示例都有具有所有相等整数[*]的输出列表,这在一般情况下当然是不可能的。

[*]除了一个,你似乎希望之前的项目更大,后面的项目更小,独立于大或小的原始项目;如果 实际上是您的规范,请参见稍后。

假设(你从来没有真正打扰那,你知道! - )"所有项目整数"是一个约束,我从

开始
minel = sum(l) // len(l)

这是分配给每个输出元素的最小值。这留下了短缺"的

numex = sum(l) - minel * len(l)

必须设置为minel + 1以保持sum相等的项目(您从未明确表达的另一个约束......: - )。

哪些?大概是那些最大的那些。

(补充:或者不是,根据你的上一个例子,似乎需要做大的项目才是最早的。如果是这样的话,那么显然:

[minel+1] * numex + [minel] * (len(l) - numex)

会好的。答案的其余部分假设您可能希望输入项的某些连接到相应的输出项,这是一个更难的问题。)

所以选择那些,例如bigs = set(heapq.nlargest(l, numex))

[minel + (x in bigs) for x in l]

将非常接近"均衡"你寻找的列表(利用bool在算术中值0或1的事实: - )。

一个小故障是针对包含重复项的列表 - 超过numex项可能满足x in bigs测试!

在这种情况下,你可能想要随机选择哪些 numex项目增加1(其他人保持在minel)。但是在你完全不明确的欲望中准确地猜测你想要什么样的情况就是猜测得太多了,所以我现在就让它停留在这里 - 你可以澄清你的规格,理想情况下用这个例子说明这个通过适当地编辑你的问题,公式不会做你想要的和你想要的东西。

答案 1 :(得分:2)

你走了。只需找到整数平均值和余数,然后返回适当数量的average+1average元素即可得到相同的总和。下面的代码利用内置divmod来给出整数和余数,以及将[x]*5等列表相乘的事实会返回[x,x,x,x,x]

def equal(l):
    q,r = divmod(sum(l),len(l))
    return [q+1]*r + [q]*(len(l)-r)

print(equal([2,1]))
print(equal([1, 4, 1]))
print(equal([2, 4, 5, 9]))
print(equal([2, 2]))
print(equal([1, 2, 3, 4, 5, 6, 7, 8, 9]))
print(equal([2, 4, 6, 8, 10, 20, 30, 40]))
print(equal([343, 452, 948, 283, 394, 238, 283, 984, 236, 847, 203]))

输出:

[2, 1]
[2, 2, 2]
[5, 5, 5, 5]
[2, 2]
[5, 5, 5, 5, 5, 5, 5, 5, 5]
[15, 15, 15, 15, 15, 15, 15, 15]
[474, 474, 474, 474, 474, 474, 474, 474, 473, 473, 473]