chw21
chw21

Reputation: 8140

Distribute number randomly into bins

I want to distribute a number randomly into different bins. What I'm doing at the moment is this:

import random

red = 0
blue = 0
green = 0
yellow = 0

for _ in range(n):
    t = random.randrange(4)
    if (t == 0):
        red += 1
    elif (t == 1):
        blue += 1
    elif (t == 2):
        green += 1
    else:
        yellow += 1

This does what I want (I think), but it looks almost ridiculously convoluted. I was wondering whether there was something better. I tried

random.choice([red, blue, green, yellow])+=1

but of course this doesn't work.

Upvotes: 0

Views: 902

Answers (3)

VicN
VicN

Reputation: 351

Maybe something like this, if you prefer a one-liner:

red, blue, green, yellow = (random.randrange(n) for _ in range(4))

EDIT: My answer is actually not correct for the problem at hand since the sum of all colors has to be "n" (which is not necessarily the case with my method).

Better (correct) solution, still a one-liner:

import numpy as np
n=100
red, blue, green, yellow = np.unique(np.random.randint(0,4,n),return_counts=True)[1]

Upvotes: 1

Nick
Nick

Reputation: 147216

You could use a dictionary of counts:

import random

counts = { 'red' : 0, 'blue' : 0, 'green' : 0, 'yellow' : 0 }
keys = [k for k in counts.keys()]

n = 100
for _ in range(n):
    counts[random.choice(keys)] += 1
    
print(counts)

Sample output:

{'red': 30, 'blue': 21, 'green': 28, 'yellow': 21 }

Upvotes: 1

AKX
AKX

Reputation: 169318

Set up a list of 4 zeroes, modify it based on the random index, then unpack into the 4 variables you want.

import random

bins = [0, 0, 0, 0]

for _ in range(n):
    bins[random.randrange(4)] += 1

red, blue, green, yellow = bins

If you have more "variables", you could use collections.Counter(), which is dict-like:

import random
import collections

counts = collections.Counter()
things = ["foo", "bar", "baz", "quux", "spam", "eggs", "hernekeitto", "viina", "teline", "johannes"]

for _ in range(n):
    counts[random.choice(things)] += 1

print(counts.most_common())  # Handy!

Upvotes: 4

Related Questions