Divide a number in arbitrary sizes in Python

I have x = 10

and y = 100

.

Can I distribute elements y

in arbitrary sized chunks among x

'element holders ??

I want to create categories x

, each with a random number of items; however, the number of items created must be accurate y

.

I think something like

# number of categories and items
x = 10, y = 100

# keep track of how many items we have left to add
y_left = y

# create all categories
for i in range(x):
    # create category

    # find number of items in this category
    num_items_in_category = random.randint(1, y_left)

    # create items
    for j in range(num_items_in_category):
        # create item

    # set new number of items left to add
    y_left -= num_items_in_category

      

+3


source to share


3 answers


Using the functions from this answer , you can generate a list of x random numbers that sum to y.

Iterate through the elements of this list and make as many random selections (deleting) from the collection of elements for each holder.

Or for example:

# requires RandIntVec() & RandFloats() from linked answer

# whatever population you are choosing from, example letter
population = list('qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890')

# sizes (whatever you want)
num_of_holders = 7
total_elements = len(population)

# empty holder to put results in
element_holder = [[] for _ in xrange(num_of_holders)]

# distribute total_elements elements in randomly-sized portions among num_of_holders 'element holders' 
random_portions_in_holder = RandIntVec(num_of_holders, total_elements, Distribution=RandFloats(num_of_holders))

# assign each portion of elements to each 'holder'
for h, portion in enumerate(random_portions_in_holder):
    for p in range(portion):
        index = random.randrange( len(population) )
        element_holder[h].append(population.pop(index))

# display
print 'Randomly-portioned elements'
for h in element_holder:
    print h

# verify
print '\nMatch desired result?'
print 'total_elements      :', total_elements
print 'elements in holders :', sum([len(h) for h in element_holder])
print 'match               :', total_elements == sum([len(h) for h in element_holder])

      



Output

Randomly-portioned elements
['M', 'N', 'f', 'V', 'v', 'h', 'i', 'H', '6', '5', 'j', '7', 'r']
['u', 'Z', 'C', 'I', 's', 'm', 'g', 'p', 'q', 'a', 'O', 'T', 'L']
['K', 'E', 'P', 'U']
['Y', 'D', 'A', 'l', 'J', 'R', 'b', 'c', 'z', 'F']
['0', '1', 'o', 'X', 'G', '4', 'W', '3', '2']
['d', 'Q']
['e', 'y', 'B', '8', 'x', 'k', 'w', 't', 'S', 'n', '9']

Match desired result?
total_elements      : 62
elements in holders : 62
match               : True

      

PS I had some indentation errors when I copied related functions, you may need to fix them. The pod code elif Distribution.lower() == 'normal':

must be at level un given level 1. I posted an edited version (end of approval), so depending on when you copy you may or may not need to edit.

+1


source


It's not too difficult. Let's create our containers:



import random

num_containers = 10
num_objects = 100

containers = [[] for _ in range(num_containers)]
objects = (some_object() for _ in range(num_objects))
# we don't need a list of these, just have to iterate over it, so this is a genexp

for object in objects:
    random.choice(containers).append(object)

      

+1


source


I faced a similar problem in my work and solved the problem using a dictionary.

import random
# number of categories (number of keys in the dictionary) and items (sum of all the value)
x, y = 10, 100

snpDict = {}
i = 0
while i < y:
    a = random.randint(0, x)
    if a in snpDict:
        snpDict[a] += 1
    else:
        snpDict[a] = 1

    i += 1

      

I have a huge number of categories and items, the performance is not very good.

0


source







All Articles