I am trying to randomly swap 2 items in each list within a list, where those to be swapped are not in another list.
Here is my code
import random
def swap(mylist):
remain = [[1, 2], [4], [], [8, 2], [1, 4], [5, 2, 1], [], [9, 5], [7]]
for x in range(0, 9):
remaining = set(mylist[x]) - set(remain[x])
to_swap = random.sample(remaining, 2)
mylist[x][mylist[x].index(to_swap[0])], mylist[x][mylist[x].index(to_swap[1])] = mylist[x][mylist[x].index(to_swap[1])], mylist[x][mylist[x].index(to_swap[0])]
return mylist
print(swap([[8, 5, 4, 1, 3, 9, 7, 6, 2], [9, 3, 5, 6, 4, 7, 1, 2, 8], [7, 3, 2, 5, 4, 1, 9, 6, 8], [2, 1, 3, 8, 6, 9, 5, 7, 4], [1, 2, 3, 5, 7, 4, 9, 8, 6], [6, 9, 3, 1, 7, 4, 2, 8, 5], [1, 2, 7, 4, 3, 8, 5, 9, 6], [3, 7, 8, 4, 1, 5, 9, 6, 2], [4, 2, 6, 5, 7, 1, 9, 3, 8]]))
Whenever I run this and print out the result, it just prints out my input again.
Does anyone know what is wrong with my code?
Thanks.
Your code performs the swaps with about one half of the sublists. I wonder what the reason of this behavior is *(see below).
If you rewrite the swapping part like this:
i = mylist[x].index(to_swap[0])
j = mylist[x].index(to_swap[1])
mylist[x][i], mylist[x][j] = mylist[x][j], mylist[x][i]
then it works.
UPDATE:
There is no need to access the lists on the right-hand side of the assignment, since we already know the values, so the updated answer would be:
i = mylist[x].index(to_swap[0])
j = mylist[x].index(to_swap[1])
mylist[x][i], mylist[x][j] = to_swap[1], to_swap[0]
*UPDATE 2:
The above mentioned behavior is caused by the fact that in multiple assignments, expressions on the left-hand side are evaluated one by one from left to right. That means the OP's code didn't work in cases where index(to_swap[0]) < index(to_swap[1])
.
Example: values 5 and 6 in the first sublist [8, 5, 4, 1, 3, 9, 7, 6, 2]
. First, the program will do
mylist[x][mylist[x].index(5)] = 6
modifying the list to [8, 6, 4, 1, 3, 9, 7, 6, 2]
. Second, the program will do
mylist[x][mylist[x].index(6)] = 5
modifying it back to [8, 5, 4, 1, 3, 9, 7, 6, 2]
.