Sinoda
Sinoda

Reputation: 245

How to shuffle a list in Python

def make_sorted_deck():
     ''' Return a sorted deck of cards. Each card is
         represented by a string as follows:
         "queen of hearts". The cards are ordered by rank and then suit within rank.
     :return: The sorted deck of cards, as a list of strings
     EXAMPLE: make_sorted_deck() == ['2 of spades', '2 of hearts', '2 of    clubs', ..., 'ace of clubs', 'ace of diamonds'] '''
     #Hint: Use the previous functions and two nested for loops.
     sorted_deck = []
     for i in get_ranks():
         for j in get_suits():
             sorted_deck.append("{0} of {1}".format(i,j))
         return sorted_deck
     print(make_sorted_deck())

def shuffle(deck):
    ''' Randomly shuffle the cards in deck into a newly created deck of cards (list).
    :param: deck: A deck of cards
    :return: A new list, consisting of a random shuffle of deck.
    EXAMPLE: shuffle(['2 of hearts', '3 of diamonds', 'jack of spades', '2 of   clubs']) could return ['jack of spades', '3 of diamonds', '2 of hearts', '2 of clubs'] 
     #REQUIREMENTS: Please implement the following algorithm: Use a while loop to repeatedly pick a random card from deck, remove it, and add it to a newly created list. '''

How would I shuffle the list created by make_sorted_deck()?

I know there is a a function that I can import to shuffle the deck, but the way I am required to do it is to take out 1 random card and append it to a new list to have a shuffled list.

Upvotes: 0

Views: 2425

Answers (2)

gboffi
gboffi

Reputation: 25023

Another answer that doesn't answer the OP question...

To shuffle a list of length n you need a list of indices, going from 0 to n-1, in random order...

We start importing the randrange function from the random module,

from random import randrange

that invoked like this randrange(n) returns a random integer i, 0 <= i <= n-1.

When we choose a first random index, between 0 and n-1 included, we have that the next index would be chosen in a narrower interval, and so on and so on...

l = [randrange(n-i) for i in range(n)]

of course the last number in l will be 0 because i==n-1 and randrange(1) has to return 0.

The numbers in l cannot be used directly to address the list to shuffle, because they refer to the position in the list of available elements at a certain point of the shuffling procedure, so for each number in n we have to see how many elements have already been shuffled, and their position relative to the current element, let's say that we want to store the _real_indices in a list, initially empty

indices = []

we have to be careful...

for i in l:                       # the randomized, partial indices
    j = 0                         # aux variable
    while j <= i:                 # we will increment j later
        if j in indices:          # if this number j, smaller than i, is in the
             i += 1               # list of used indices, i must be incremented
        j += 1
    indices.append(i)             # the (possibly) incremented i is stored

and that's all for shuffling.

Here I report a short IPython session that demonstrates the correctness of this approach:

In [1]: from random import randrange

In [2]: def shuffle(n):
    l = [randrange(n-i) for i in range(n)]
    indices = []
    for i in l:
        j = 0
        while j <= i:
            if j in indices: i = i+1
            j = j+1
        indices.append(i)
    return indices
   ...: 

In [3]: sh = shuffle(10) ; print sh ; print sorted(sh)
[7, 6, 4, 9, 1, 5, 0, 2, 8, 3]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

In [4]: sh = shuffle(10) ; print sh ; print sorted(sh)
[6, 9, 5, 1, 4, 3, 0, 2, 8, 7]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

In [5]: sh = shuffle(10) ; print sh ; print sorted(sh)
[3, 6, 4, 9, 0, 7, 8, 1, 2, 5]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

In [6]: 

Upvotes: 0

Daniel Hepper
Daniel Hepper

Reputation: 29967

I'm not going to solve your homework, but let me give you some hints:

  • while x: will loop as long as x is true-ish. A non-empty list is true-ish.

  • you can choose a random number x where 0 <= x < n by doing x = random.randrange(n) (docs)

  • You can remove the item with index i from a list l (i.e. l[i]) by using l.pop(i) (docs)

Upvotes: 3

Related Questions