Quiero distribuir un número al azar en diferentes contenedores. Lo que estoy haciendo en este momento es esto:

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

Esto hace lo que quiero (creo), pero parece casi ridículamente complicado. Me preguntaba si había algo mejor. Lo intenté

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

Pero, por supuesto, esto no funciona.

0
chw21 26 jun. 2020 a las 11:00

3 respuestas

La mejor respuesta

Configure una lista de 4 ceros, modifíquela en función del índice aleatorio, luego descomprímala en las 4 variables que desee.

import random

bins = [0, 0, 0, 0]

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

red, blue, green, yellow = bins

Si tiene más "variables", puede usar collections.Counter(), que es como un dict:

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!
4
AKX 26 jun. 2020 a las 08:02

Tal vez algo como esto, si prefiere una línea:

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

EDITAR: Mi respuesta en realidad no es correcta para el problema en cuestión, ya que la suma de todos los colores debe ser "n" (que no es necesariamente el caso con mi método).

Mejor (correcta) solución, todavía un trazo:

import numpy as np
n=100
red, blue, green, yellow = np.unique(np.random.randint(0,4,n),return_counts=True)[1]
1
VicN 26 jun. 2020 a las 11:38

Podrías usar un diccionario de recuentos:

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)

Salida de muestra:

{'red': 30, 'blue': 21, 'green': 28, 'yellow': 21 }
1
Nick 26 jun. 2020 a las 08:04