9

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)
HeelMega
  • 458
  • 8
  • 23
  • What about, random.choice(list(users), num_of_user)? – Benny Elgazar Dec 20 '21 at 18:45
  • What deprecation warning do you get? Usually deprecation warnings give you an alternative – Pranav Hosangadi Dec 20 '21 at 18:45
  • What message do you get exactly? As a workaround you could convert your set into a list and pass this list to `.sample()`. – albert Dec 20 '21 at 18:46
  • Sampling from a set deprecated since Python 3.9 and will be removed in a subsequent version. @albert – HeelMega Dec 20 '21 at 18:46
  • @PranavHosangadi please see above message – HeelMega Dec 20 '21 at 18:47
  • discord.ext.commands.errors.CommandInvokeError: Command raised an exception: TypeError: choice() takes 2 positional arguments but 3 were given @BennyElgazar – HeelMega Dec 20 '21 at 18:48
  • Please see the docs for [`.sample()`](https://docs.python.org/3/library/random.html#random.sample) and [`.choices()`](https://docs.python.org/3/library/random.html#random.choices) for further details and how these functions differ. – albert Dec 20 '21 at 18:50
  • 1
    Can you turn your set into a list? `random_users = random.choices([*users],k=num_of_user)` – DanielTuzes Dec 20 '21 at 18:55
  • @DanielTuzes 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 question – HeelMega Dec 20 '21 at 18:57

2 Answers2

9

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.

DanielTuzes
  • 2,494
  • 24
  • 40
1

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.

Marcin Owsiany
  • 486
  • 5
  • 8