2

I have a list of tuples looking like... deck=[(1,'clubs'),(1,'hearts')...and so on to (13,'diamonds').

How do I randomize this list into something like...

[(5,'spades'),(12,'clubs'),(3,'clubs'),... and so on?

I have tried using random.randint() and nothing seems to work. And I can not use random.shuffle()

Drake Robison
  • 33
  • 1
  • 5

3 Answers3

3

You want random.shuffle():

>>> import random
>>> l = [1, 2, 3, 4, 5]
>>> random.shuffle(l)
>>> l
[2, 1, 5, 3, 4]

Since it seems you can't use random.shuffle, perhaps your teacher wanted you to use random.randint() to get a random number between 1-13, then a random suit (hearts, clubs, diamonds, spades), and form a list like that. Keep in mind you'll need to check if the card already exists in the list.

Try have an attempt first, but if you can't do it, then here's the solution. I strongly recommend you have a go first using the approach I just mentioned above.

l = []
while len(l) < 52:
    number = random.randint(1, 13)
    suit = random.choice(['hearts', 'clubs', 'diamonds', 'spades'])
    card = (number, suit)
    if card not in l:
        l.append(card)
TerryA
  • 58,805
  • 11
  • 114
  • 143
  • I am not allowed to use random.shuffle() is there another way? – Drake Robison Sep 25 '15 at 00:58
  • @DrakeRobison Why aren't you allowed to use `random.shuffle`? – TerryA Sep 25 '15 at 00:58
  • Oh, I think I know what approach your teacher wants. Let me work something out – TerryA Sep 25 '15 at 01:02
  • @DrakeRobison Sorry it took so long. I was trying to format my answer so that there would be a spoiler tag so you would have a go. I **strongly recommend** you have a go first with the explanation I included in my answer – TerryA Sep 25 '15 at 01:12
  • 1
    @TerryA: I had downvoted this answer because it did not answer the actual question that the OP asked, i.e. how to shuffle a _pre-existing_ list without using `random.shuffle()`. However, because the OP now says it's what was wanted, I have retracted the down vote. – mhawke Sep 25 '15 at 01:23
1

If you want to shuffle a pre-existing list, rather than creating it already shuffled, it's not hard to do work fairly similar to what random.shuffle likely does (I'm intentionally avoiding checking the source code to avoid guilty knowledge here):

deck = [(1,'clubs'),(1,'hearts')...]
for i, card in enumerate(deck):
    swapi = random.randrange(i, len(deck))
    deck[i], deck[swapi] = deck[swapi], card

All that does is swap each card in the deck with a card at or after it, and by doing so for every card, the end result maintains none of the order of the original deck.

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
  • I've been told by a more experienced colleague to avoid this kind of method. Apparently its much better to use Numpy to achieve this instead. See: https://blog.codinghorror.com/the-danger-of-naivete/ – Laurie Jul 13 '18 at 11:08
  • @LaurieBamber: This is *not* the naive solution mentioned in your link. That solution swaps each location once with every other possible location (that is, it swaps index 0 with a random index from 0 to n, then index 1 with a random index from 0 to n, etc.). My solution, by using `random.randrange(i, len(deck))` (*not* `randrange(len(deck))`), ends up with the same combinatoric properties as the Knuth-Fisher-Yates shuffle in your link, swapping 0 with 0-n, then 1 with *1*-n, etc., essentially selecting a single value to occupy each slot from the set of unselected values remaining as it goes. – ShadowRanger Jul 13 '18 at 16:14
  • As for using `numpy`, the OP was explicitly forbidden to use `random.shuffle`; I doubt using `numpy` equivalents would be acceptable. – ShadowRanger Jul 13 '18 at 16:14
  • Fair enough, I don't know enough to comment about this, my colleague just said he thought this method might produce the same problems as listed in the provided article. Is random part of the numpy library? I though random was seperate. – Laurie Jul 13 '18 at 16:26
  • @LaurieBamber: You brought up `numpy` as a better way to achieve this, which is the only reason I mentioned it; no, `random` and `numpy.random` aren't the same, but they're both predefined APIs that do the work for you, and the OP was trying to implement without using a predefined API (as the teacher forbade it). If they're that early in their Python class, jumping to `numpy` (third party, more magical than the Python builtins) isn't going to teach them the right approach. – ShadowRanger Jul 13 '18 at 16:29
0
   import time
   test_list = [r for r in range(20)]
   print("The original list is : " + str(test_list))
   for i in range(len(test_list)):
    n=str(time.time())[-1]
    j=int(n)

    # Swap arr[i] with the element at random index
    if j < len(test_list):
     test_list[i], test_list[j] = test_list[j], test_list[i]

   print("The shuffled list is : " + str(test_list))
y durga prasad
  • 1,184
  • 8
  • 11