Choosing and shuffling
Random numbers are often just a way to pick something: a question, a card, a player. The random module has functions that do the picking directly.
choice
random.choice(items) picks one item of a list, each with the same chance. It works on a string too, and then picks one character:
import random
random.seed(3)
snacks = ["apple", "nuts", "yogurt", "carrot sticks"]
print("Today's snack:", random.choice(snacks))
print("A random letter:", random.choice("ABCDEFG"))
Today's snack: nuts
A random letter: EYou could get the same with snacks[random.randint(0, len(snacks) - 1)], but choice is shorter, and there's no index to get wrong.
shuffle
random.shuffle(items) puts the items of a list in a random order. Like the sort method, it changes the list itself, in place, and returns nothing:
import random
random.seed(4)
cards = ["ace", "king", "queen", "jack"]
random.shuffle(cards)
print(cards)
['queen', 'ace', 'jack', 'king']Since it returns nothing, a common mistake is to store its result. shuffle returns None, so the next line replaces the list with None, and the program fails when it uses the list:
import random
cards = ["ace", "king", "queen", "jack"]
cards = random.shuffle(cards)
print(cards[0])
Traceback (most recent call last):
File "main.py", line 5, in <module>
print(cards[0])
~~~~~^^^
TypeError: 'NoneType' object is not subscriptableCall it on a line of its own: random.shuffle(cards).
Keeping the original order
Because shuffle changes the list, the original order is gone. When you need both, shuffle a copy. As you saw with references, cards[:] makes a new list with the same items:
import random
random.seed(4)
cards = ["ace", "king", "queen", "jack"]
deck = cards[:]
random.shuffle(deck)
print("Shuffled:", deck)
print("Original:", cards)
Shuffled: ['queen', 'ace', 'jack', 'king']
Original: ['ace', 'king', 'queen', 'jack']A string can't be shuffled at all: strings can't be changed, and shuffle works by moving items around inside the list it's given.