Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swap two values randomly in list

I have the following list:

a = [1, 2, 5, 4, 3, 6]

And I want to know how I can swap any two values at a time randomly within a list regardless of position within the list. Below are a few example outputs on what I'm thinking about:

[1, 4, 5, 2, 3, 6]
[6, 2, 3, 4, 5, 1]
[1, 6, 5, 4, 3, 2]
[1, 3, 5, 4, 2, 6]

Is there a way to do this in Python 2.7? My current code is like this:

import random
n = len(a)
if n:
    i = random.randint(0,n-1)
    j = random.randint(0,n-1)
    a[i] += a[j]
    a[j] = a[i] - a[j]
    a[i] -= a[j]

The issue with the code I currently have, however, is that it starts setting all values to zero given enough swaps and iterations, which I do not want; I want the values to stay the same in the array, but do something like 2opt and only switch around two with each swap.

like image 235
Leggerless Avatar asked Sep 10 '25 18:09

Leggerless


1 Answers

You are over-complicating it, it seems. Just randomly sample two indices from the list, then swap the values at those indicies:

>>> def swap_random(seq):
...     idx = range(len(seq))
...     i1, i2 = random.sample(idx, 2)
...     seq[i1], seq[i2] = seq[i2], seq[i1]
...
>>> a
[1, 2, 5, 4, 3, 6]
>>> swap_random(a)
>>> a
[1, 2, 3, 4, 5, 6]
>>> swap_random(a)
>>> a
[1, 2, 6, 4, 5, 3]
>>> swap_random(a)
>>> a
[1, 2, 6, 5, 4, 3]
>>> swap_random(a)
>>> a
[6, 2, 1, 5, 4, 3]

Note, I used the Python swap idiom, which doesn't require an intermediate variable. It is equivalent to:

temp = seq[i1]
seq[i1] = seq[i2]
seq[i2] = temp
like image 157
juanpa.arrivillaga Avatar answered Sep 13 '25 07:09

juanpa.arrivillaga