âHelp me!, I would like to find split where the split sums are close to each other?
<p>I have a list is</p>

<blockquote>
  <p>test = [10,20,30,40,50,60,70,80,90,100]</p>
</blockquote>

<p>âand I would like to find split where the split sums are close to each other by number of splits = 3 that âall possible combinations and select the split where the sum differences are smallest.</p>

<p>please example code or simple code Python.</p>

<p>Thank you very much</p>

<p>K.ademarus</p>

<p>This first script uses a double <code>for</code> loop to split the input list into all possible triplets of lists. For each triplet it calculates the sum of each list in the triplet, then creates a sorted list named <code>diffs</code> of the absolute differences of those sums. It saves a tuple consisting of <code>diffs</code> followed by the triplet into a list named <code>all_splits</code>. Finally, it sorts <code>all_splits</code>, and because each item in <code>all_splits</code> begins with <code>diffs</code> the saved tuples are sorted in order of their <code>diffs</code> from lowest to highest.</p>

<pre><code>def split_list_test(lst):
    all_splits = []
    for i in range(1, len(lst) - 1):
        for j in range(i + 1, len(lst)):
            splits = [lst[:i], lst[i:j], lst[j:]]
            a, b, c = map(sum, splits)
            diffs = sorted((abs(c-a), abs(c-b), abs(b-a)), reverse=True)
            all_splits.append((diffs, splits))
    all_splits.sort()
    return all_splits

test = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]

for row in split_list_test(test):
    print(row)
</code></pre>

<p><strong>output</strong></p>

<pre><code>([60, 40, 20], [[10, 20, 30, 40, 50], [60, 70, 80], [90, 100]])
([60, 40, 20], [[10, 20, 30, 40, 50, 60], [70, 80], [90, 100]])
([140, 110, 30], [[10, 20, 30, 40, 50, 60], [70, 80, 90], [100]])
([140, 120, 20], [[10, 20, 30, 40, 50], [60, 70], [80, 90, 100]])
([160, 90, 70], [[10, 20, 30, 40], [50, 60, 70, 80], [90, 100]])
([170, 90, 80], [[10, 20, 30, 40], [50, 60, 70], [80, 90, 100]])
([180, 110, 70], [[10, 20, 30, 40, 50, 60, 70], [80, 90], [100]])
([200, 110, 90], [[10, 20, 30, 40, 50, 60, 70], [80], [90, 100]])
([200, 140, 60], [[10, 20, 30, 40, 50, 60], [70], [80, 90, 100]])
([200, 150, 50], [[10, 20, 30, 40, 50], [60, 70, 80, 90], [100]])
([210, 160, 50], [[10, 20, 30], [40, 50, 60, 70], [80, 90, 100]])
([240, 130, 110], [[10, 20, 30], [40, 50, 60, 70, 80], [90, 100]])
([240, 220, 20], [[10, 20], [30, 40, 50, 60, 70], [80, 90, 100]])
([240, 230, 10], [[10, 20, 30, 40], [50, 60], [70, 80, 90, 100]])
([250, 250, 0], [[10, 20, 30, 40], [50, 60, 70, 80, 90], [100]])
([260, 260, 0], [[10], [20, 30, 40, 50, 60, 70], [80, 90, 100]])
([270, 260, 10], [[10, 20, 30, 40, 50, 60, 70, 80], [90], [100]])
([280, 190, 90], [[10, 20, 30], [40, 50, 60], [70, 80, 90, 100]])
([280, 190, 90], [[10, 20, 30, 40, 50], [60], [70, 80, 90, 100]])
([300, 160, 140], [[10, 20], [30, 40, 50, 60, 70, 80], [90, 100]])
([310, 160, 150], [[10, 20], [30, 40, 50, 60], [70, 80, 90, 100]])
([330, 190, 140], [[10], [20, 30, 40, 50, 60], [70, 80, 90, 100]])
([330, 290, 40], [[10, 20, 30], [40, 50, 60, 70, 80, 90], [100]])
([340, 180, 160], [[10], [20, 30, 40, 50, 60, 70, 80], [90, 100]])
([340, 310, 30], [[10, 20, 30], [40, 50], [60, 70, 80, 90, 100]])
([350, 300, 50], [[10, 20, 30, 40], [50], [60, 70, 80, 90, 100]])
([370, 280, 90], [[10, 20], [30, 40, 50], [60, 70, 80, 90, 100]])
([390, 260, 130], [[10], [20, 30, 40, 50], [60, 70, 80, 90, 100]])
([390, 320, 70], [[10, 20], [30, 40, 50, 60, 70, 80, 90], [100]])
([410, 390, 20], [[10, 20, 30], [40], [50, 60, 70, 80, 90, 100]])
([420, 380, 40], [[10, 20], [30, 40], [50, 60, 70, 80, 90, 100]])
([430, 340, 90], [[10], [20, 30, 40, 50, 60, 70, 80, 90], [100]])
([440, 360, 80], [[10], [20, 30, 40], [50, 60, 70, 80, 90, 100]])
([460, 460, 0], [[10, 20], [30], [40, 50, 60, 70, 80, 90, 100]])
([480, 440, 40], [[10], [20, 30], [40, 50, 60, 70, 80, 90, 100]])
([510, 500, 10], [[10], [20], [30, 40, 50, 60, 70, 80, 90, 100]])
</code></pre>

<hr>

<p>The next script is a little more compact, and it only returns a single solution. It uses a different rule to decide on the minimal split. If <code>(a, b, c)</code> are the sums of the lists in a triplet, sorted from lowest to highest, then the absolute differences of those sums are <code>c-a</code>, <code>c-b</code>, and <code>b-a</code>. The sum of the differences is <code>c-a + c-b + b-a</code> which is equal to <code>2*(c-a)</code>, so we can find the minimal split (using this rule) by looking for the split with the minimal value of <code>c-a</code>.</p>

<pre><code>def keyfunc(seq):
    sums = sorted(sum(u) for u in seq)
    return sums[2] - sums[0]

def split_list(lst):
    gen = ([lst[:i], lst[i:j], lst[j:]]
        for i in range(1, len(lst) - 1)
            for j in range(i + 1, len(lst)))
    return min(gen, key=keyfunc)

test = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
print(split_list(test))
</code></pre>

<p><strong>output</strong></p>

<pre><code>[[10, 20, 30, 40, 50], [60, 70, 80], [90, 100]]
</code></pre>

<p>As you can see, for this <code>test</code> list this version gives the same solution as one of the minimal solutions found above.</p>

python python-2.7 python-3.x recursion split