How to generate numbers in range with specific average with Python?
<p>For example I would like to generate 22 numbers between 20 and 46 with an average value of 27. And I would like the numbers to cover the range as well as possible.</p>

<p>EDIT:
These numbers don't need to be random.</p>

<p>You could sove this in a pure mathematical way. <br/></p>

<ol>
<li>Randomly pick a number (call it n) within the wanted range</li>
<li>The next number will be avg + abs(n-avg)</li>
<li>repeat this until you fill the amount of numbers you want</li>
</ol>

<p>if the amount of needed numbers is no even - just select one of the numbers as the average itself and then you will need to generate k-1 numbers (which is even)</p>

<p>** <strong>EDIT</strong> **<br/>
you can use this code that manipulates an initial list to meet the requirements of a average so the resulting list is not symmetrical. (Better than generating lists until you hit the correct one)</p>

<pre><code>import random


def generate_numbers(wanted_avg, numbers_to_generate, start, end):
    rng = [i for i in range(start, end)]
    initial_selection = [random.choice(rng) for _ in range(numbers_to_generate)]
    initial_avg = reduce(lambda x, y: x+y, initial_selection) / float(numbers_to_generate)
    print "initial selection is: " + str(initial_selection)
    print "initial avg is: " + str(initial_avg)
    if initial_avg == wanted_avg:
        return initial_selection
    off = abs(initial_avg - wanted_avg)
    manipulation = off * numbers_to_generate

    sign = -1 if initial_avg &gt; wanted_avg else 1

    manipulation_action = dict()
    acceptable_indices = range(numbers_to_generate)
    while manipulation &gt; 0:
        random_index = random.choice(acceptable_indices)
        factor = manipulation_action[random_index] if random_index in manipulation_action else 0
        after_manipulation = initial_selection[random_index] + factor + sign * 1
        if start &lt;= after_manipulation &lt;= end:
            if random_index in manipulation_action:
                manipulation_action[random_index] += sign * 1
                manipulation -= 1
            else:
                manipulation_action[random_index] = sign * 1
                manipulation -= 1
        else:
            acceptable_indices.remove(random_index)

    for key in manipulation_action:
        initial_selection[key] += manipulation_action[key]

    print "after manipulation selection is: " + str(initial_selection)
    print "after manipulation avg is: " + str(reduce(lambda x, y: x+y, initial_selection) / float(numbers_to_generate))
    return initial_selection
</code></pre>

python math