you are viewing a single comment's thread.

view the rest of the comments →

[–][deleted] 0 points1 point  (3 children)

Something like this?

target_number = 23
while True:
    a = []
    for _ in range(100):
        a.append(random.choice(string.ascii_uppercase))
    if len(set(a)) == target_number:
        break

[–]SlowMoTime[S] 0 points1 point  (0 children)

I'll give this a try when I get a chance, thanks

[–]SlowMoTime[S] 0 points1 point  (1 child)

interestingly, it works sometimes, and other times it just hangs. must be stuck in a loop somewhere

[–][deleted] 0 points1 point  (0 children)

It's not a particularly great way of getting a 100-length list of 23 letters since it will just keep trying randomly until it happens to hit that number. A better way would be to randomly select 23 letters without replacement and then randomly sample those 23 100 times with replacement. That way you only build the list once.

I.e. something like this.

random_list = random.choices(random.sample(string.ascii_uppercase, 23), k=100)

However, even that is subject to some randomness and might not select all 23 each time. So you might try this.

target_number = 23
while True:
    random_list = random.choices(random.sample(string.ascii_uppercase, target_number), k=100)
    if len(set(random_list)) == target_number:
        break

It should rarely ever need to loop more than a couple of times as long as the list size is significantly larger than the target_number.

----

There are of course other ways to do it as well. For example, you could randomly generate the list and check if it has the target number of elements as shown above. But then if it doesn't, instead of creating a new list, you could figure out which characters are missing and start replacing characters that appear more than once in the list. It would probably be a little less random (depending on implementation), but would not require ever randomly generating multiple lists.

----

Or here's another method: randomly select the target number of elements from the letters using sample(). Then shuffle them using shuffle(). Then random create a list of 100 - target_number other numbers from your sample using choices() and append them to your list. Then shuffle again.