I was looking at some statistical evaluations of a dice roll and stumbled onto this strange result:

import random

# faces of a dice
dice = [1, 2, 3, 4, 5, 6]

rolls = []
for k in range(3):
    random.shuffle(dice)
    #test
    print dice
    rolls.append(dice)

# test
print rolls

"""
my strange output -->
[3, 2, 6, 1, 5, 4]
[6, 2, 1, 5, 4, 3]
[1, 5, 2, 6, 3, 4]
[[1, 5, 2, 6, 3, 4], [1, 5, 2, 6, 3, 4], [1, 5, 2, 6, 3, 4]]
"""

There is nothing strange, the shuffle happens in place, so rolls contains 3 references to the same list. You should write rolls.append(list(dice)) if you want to keep the intermediary states of the dice.

Thanks, that works. However, since dice is already a list, why do I have to use list(dice)?

Or you could append a copy of the list

import random
 
# faces of a dice
dice = [1, 2, 3, 4, 5, 6]
 
rolls = []
for k in range(3):
    random.shuffle(dice)
    #test
    print dice
    rolls.append(dice[:])
 
# test
print rolls
#
"""  My test
[5, 2, 4, 6, 1, 3]
[2, 4, 1, 6, 5, 3]
[5, 6, 4, 3, 1, 2]
[[5, 2, 4, 6, 1, 3], [2, 4, 1, 6, 5, 3], [5, 6, 4, 3, 1, 2]]
"""

The effect of list(dice) is the same as dice[:] : it returns a copy of the list. It's important to understand that python methods manipulate references to python objects. When you write dice = [1,2,3,4,5] , python creates a list which is stored somewhere in memory, but the variable dice contains only a reference to this list (it's address in memory). The statement rolls.append(dice) adds a new reference to the same segment of memory in the list rolls . An expression like list(dice) copies the content of the list in a new segment of memory and returns a reference to this new list.

This article has been dead for over six months. Start a new discussion instead.