Get random number from set deprecation
Asked Answered
T

2

11

I am trying to get a random n number of users from a set of unique users.

Here is what I have so far

users = set()

random_users = random.sample((users), num_of_user)

This works well but it is giving me a deprecated warning. What should I be using instead? random.choice doesn't work with sets

UPDATE

I am trying to get reactions on a post and want them to be unique which is why I used a set. Would it be better to stick with a list for this?

users = set()
    for reaction in msg.reactions:
        async for user in reaction.users():
            users.add(user)
Tubbs answered 20/12, 2021 at 18:42 Comment(9)
What about, random.choice(list(users), num_of_user)?Bronwyn
What deprecation warning do you get? Usually deprecation warnings give you an alternativeArticulate
What message do you get exactly? As a workaround you could convert your set into a list and pass this list to .sample().Ondine
Sampling from a set deprecated since Python 3.9 and will be removed in a subsequent version. @OndineTubbs
@PranavHosangadi please see above messageTubbs
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: TypeError: choice() takes 2 positional arguments but 3 were given @BennyElgazarTubbs
Please see the docs for .sample() and .choices() for further details and how these functions differ.Ondine
Can you turn your set into a list? random_users = random.choices([*users],k=num_of_user)River
@River that worked. Would it be better to start with a list instead of a set? or its the best approach to convert it to a list later? Please see update in the questionTubbs
R
11

Convert your set to a list.

  1. by using the list function:

    random_users = random.choices(list(users),k=num_of_user)
    
  2. by using * operator to unpack your set or dict:

    random_users = random.choices([*users],k=num_of_user)
    

Solution 1. is 3 char longer than the 2., but solution 1. is more literal - to me.

It is not guaranteed that you will get the same result for the list order through different executions, python versions and platforms, therefore you may end up with different random result, despite a careful random number generator initialization. To resolve this issue, order your list.

You can also store the users in a list, and make the elements unique later with set, and then convert again to a list. For this, a common way is to convert your list to a set, and back to a list again.

River answered 20/12, 2021 at 19:7 Comment(3)
Why not just list(users)?Sharell
len("[*users]") < len("list(users)"), however, I'd prefer list, it seems easier to understand.River
Be careful when using random.choices instead of random.sample as in the initial post, as random.choices can return the same entry multiple times!Sad
B
2

FWIW, random.sample() in Python 3.9.2 says this when passed a dict:

TypeError: Population must be a sequence.  For dicts or sets, use sorted(d).

And this solution does seem to work for both set and dict inputs.

Boyt answered 11/1, 2022 at 15:35 Comment(1)
Why would you sort it when you're getting a random value?Sharell

© 2022 - 2024 — McMap. All rights reserved.