问题
I have a situation where I have invoice spreadsheets incoming with single rows that span multiple months with a quantity column containing the summation of the quantity for all months spanned.
In order to run month-by-month analytics, we need to split the total quantity into equal(ish) quantities across n rows where n is the number of months spanned.
These numbers can be off by one or two, but the smaller the difference between each element the better.
I have a rough mockup I did in python but I feel there's a better way to do this somehow. Note: Please excuse... everything:
from __future__ import division
import math
def evenDivide(num, div):
splits = []
sNum = str(num/div)
remainder = float(sNum[sNum.index('.'):])
#print "Remainder is " + str(remainder)
integer = math.floor(num/div)
#print "Integer is " + str(integer)
totRemainder = round(remainder * div, 2)
#print "Total Remainder is " + str(totRemainder)
for index in range(div):
if (totRemainder > 0):
totRemainder -= 1 if (index%2 == 0) else 0
if (index % 2 == 0):
splits.append(int(integer + 1))
else:
splits.append(int(integer))
else:
splits.append(int(integer))
for index in range(div):
if(totRemainder > 0):
if (index % 2 == 1):
splits[index] += 1
totRemainder -= 1
return splits
def EvalSolution(splits):
total = 0
for index in range(len(splits)):
total += splits[index]
return total
def testEvenDivide():
for index in range(20000):
for jndex in range(3, 200):
if (EvalSolution(evenDivide(index, jndex)) != index):
print "Error for " + str(index) + ", " + str(jndex)
回答1:
If space is an issue, this one-liner may help:
num, div = 15, 4
print ([num // div + (1 if x < num % div else 0) for x in range (div)])
# result: [4, 4, 4, 3]
回答2:
I assume both num and div are integers (you should mention it in your question).
You can use the modulo operator to find the remainder of the division:
remainder=num%div # i.e. 124/12 will give you 4
Integer division will give you the integer part of the result without using math.floor
integer = num/div # i.e. 124/12 will give you 10
I would return now the (integer,remainder) tuple, but if you really need all the splits in a list, you can do:
splits=[]
for i in range(div):
splits.append(integer)
for i in range(remainder):
splits[i]+=1
来源:https://stackoverflow.com/questions/20348717/algo-for-dividing-a-number-into-almost-equal-whole-numbers