4

First of all, I know that I should never attempt what I describe in this question and this is purely hypothetical so please don't yell at me.

Python sets don't maintain order because they are hash-maps without the map part. So I was wondering how well they are at randomizing things. It obviously isn't enough for crypto, and won't work on ints (because Python hash is identity on ints), but is it good enough for games and stuff?

It makes sense that it would work decently because its modding on a hash, but I'm not really sure how good that hash is and how well it'll work for randomizing.

P.S: Sets will always return the same shuffle for the same values, but you can assume that that isn't a problem.

Maltysen
  • 1,868
  • 17
  • 17
  • What do you mean by "randomize"? What do you mean by "good enough for games and stuff"? You can use set iteration order if *you don't care* about the order. If you care about the order in any way --- wanting it to be a particular way, or not be a particular way, or be predictable, or be unpredictable --- you shouldn't rely on the iteration order. – BrenBarn Dec 27 '15 at 05:53
  • this is definitely definitely not a dupe of that question – undergroundmonorail Dec 27 '15 at 05:55
  • @undergroundmonorail agreed – Adam Smith Dec 27 '15 at 05:59
  • @BrenBarn I was asking how good it was if I wanted it unpredictable. – Maltysen Dec 27 '15 at 06:02
  • @Maltysen it's horrible. It's very predictable, in fact that's the reason it exists. – Adam Smith Dec 27 '15 at 06:02
  • Python's hashing is designed to minimize hash collisions of string keys, so it might be ok for your needs. But really, it'd be much better to use shuffle or sample. – PM 2Ring Dec 27 '15 at 06:28

1 Answers1

2

a set doesn't have an order, so by definition it can't randomize order. Iteration order isn't usable if you care about order. As BrenBam says, if you care about the order in any way, you can't rely on it because it's an implementation detail.

The correct way to randomize order is random.shuffle

some_set_of_stuff = set(...)
some_list_of_stuff = list(some_set_of_stuff)  # you MUST make an ordered container for this!
random.shuffle(some_list_of_stuff)

Or you could use random.sample if you really need to.

some_set_of_stuff = set(...)
randomized = random.sample(some_set_of_stuff, len(some_set_of_stuff))
Jon Clements
  • 138,671
  • 33
  • 247
  • 280
Adam Smith
  • 52,157
  • 12
  • 73
  • 112