Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python random shuffle while loop

I'm trying to fill lists with permutations of the same initial list. I don't understand why the following is not working.

parts = [[],[]]
while len(parts[-1]) < 2:
  newval = random.choice([[1,2,3,4],[5,6,7,8]])
  for part in parts:
    random.shuffle(newval)
    part.append(newval)

Expected result would be something like: [[[6,7,8,5],[1,3,4,2]],[[5,8,6,7],[4,2,3,1]]]

like image 838
mrtnmgs Avatar asked Jul 24 '26 09:07

mrtnmgs


2 Answers

random.shuffle works in-place and consequently modifies newval. You have to make a copy when appending to part otherwise the same list (or list reference) is shuffled and stored in part.

import random

parts = [[],[]]
while len(parts[-1]) < 2:
  newval = random.choice([[1,2,3,4],[5,6,7,8]])
  for part in parts:
    random.shuffle(newval)
    part.append(newval[:])

print(parts)

possible outputs:

[[[3, 1, 2, 4], [5, 7, 6, 8]], [[1, 2, 4, 3], [6, 7, 5, 8]]]
[[[1, 3, 2, 4], [4, 2, 1, 3]], [[2, 4, 3, 1], [4, 3, 2, 1]]]
[[[7, 5, 6, 8], [3, 2, 4, 1]], [[8, 5, 6, 7], [1, 4, 3, 2]]]
like image 124
Jean-François Fabre Avatar answered Jul 26 '26 23:07

Jean-François Fabre


Because in Python everything is reference. When you append the value to the array, in fact you add the reference to the place in memory where the value is stored.

Say, you have assigned the list to the first element. When on the next iteration you re-shuffle this list, you change the value in the memory. Thus, the value you will when accessing the element you appended on previous step is also changed.

To fix this, try appending copy.copy(newval) instead of just newval (do not forget to import copy)

Here is your code changed accordingly:

import copy
parts = [[],[]]
while len(parts[-1]) < 2:
    newval = random.choice([[1,2,3,4],[5,6,7,8]])
    for part in parts:
        random.shuffle(newval)
        part.append(copy.copy(newval))
like image 24
Dmitry Torba Avatar answered Jul 27 '26 00:07

Dmitry Torba



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!