# Is there a way to shuffle pairs within a list?

## Question:

I have a pairs of names in a list that I want to shuffle for xgboost.

Input: `[['A1', 'B1'], ['A2', 'B2'], ['A3', 'B3'], ['A4', 'B4'], ['A5', 'B5'], ['A6', 'B6'], ['A7', 'B7'], ['A8', 'B8']]`

Expecting: `[['A1', 'B1'], ['B2', 'A2'], ['A3', 'B3'], ['A4', 'B4'], ['B5', 'A5'], ['A6', 'B6'], ['A7', 'B7'], ['B8', 'A8']]`

I have tried this and it does produce the results I want but I believe there’s an easy way.:

``````rand_number = random.randint(0, 1000)
tlist_rand = []
for t in tlist:
if rand_number % 3 == 0:
tlist_rand.append(random.sample(t, len(t)))
rand_number = random.randint(0, 1000)
else:
tlist_rand.append(t)
rand_number = random.randint(0, 1000)
``````

Input: `[['A1', 'B1'], ['A2', 'B2'], ['A3', 'B3'], ['A4', 'B4'], ['A5', 'B5'], ['A6', 'B6'], ['A7', 'B7'], ['A8', 'B8']]`

The rand tuple is: `[['A1', 'B1'], ['A2', 'B2'], ['A3', 'B3'], ['B4', 'A4'], ['A5', 'B5'], ['A6', 'B6'], ['A7', 'B7'], ['A8', 'B8']]`

You can use `random.shuffle`, this function can shuffle list inplace.

You can simplify your code a lot:

1. Since the elements are pairs, you don’t need to shuffle them, only reverse them. But because it’s 1/2 that a pair gets shuffled, we’ll need to double the random number to keep the same odds.
2. You don’t need to get `rand_number` in three different places, only one.

Also, there are 334 numbers divisible by 3 in [0, 1000], and 334/1001 is really close to 1/3, so might as well use the smaller number.

So ultimately I’ll use 1/6, implemented as k < 1, k in [0, 5].

``````tlist_rand = [t[::-1] if random.randrange(6) < 1 else t for t in tlist]
``````

Example output:

``````[['A1', 'B1'], ['A2', 'B2'], ['B3', 'A3'], ['A4', 'B4'], ['B5', 'A5'], ['A6', 'B6'], ['A7', 'B7'], ['A8', 'B8']]
``````

`random.shuffle` is the right tool for the job. But it mutates the list passed to it, so use it in a loop rather than a list comprehension.

``````>>> lst = [['A1', 'B1'], ['A2', 'B2'], ['A3', 'B3'], ['A4', 'B4'], ['A5', 'B5'], ['A6', 'B6'], ['A7', 'B7'], ['A8', 'B8']]
>>> import random
>>> for x in lst: random.shuffle(x)
...
>>> lst
[['A1', 'B1'], ['A2', 'B2'], ['B3', 'A3'], ['B4', 'A4'], ['B5', 'A5'], ['B6', 'A6'], ['A7', 'B7'], ['B8', 'A8']]
``````

If you need a new list you need to make a deep copy of the original list, and then you can shuffle that.

``````>>> import copy
>>> lst2 = copy.deepcopy(lst)
>>> for x in lst2: random.shuffle(x)
...
>>> lst2
[['B1', 'A1'], ['B2', 'A2'], ['B3', 'A3'], ['A4', 'B4'], ['B5', 'A5'], ['A6', 'B6'], ['B7', 'A7'], ['B8', 'A8']]
>>> lst
[['A1', 'B1'], ['A2', 'B2'], ['B3', 'A3'], ['B4', 'A4'], ['B5', 'A5'], ['B6', 'A6'], ['A7', 'B7'], ['B8', 'A8']]
``````

Looks like you want a 1 in 3 chance of swapping the two elements of each sub-list.

In which case you could do it like this:

``````from random import randint

data = [['A1', 'B1'], ['A2', 'B2'], ['A3', 'B3'], ['A4', 'B4'], ['A5', 'B5'], ['A6', 'B6'], ['A7', 'B7'], ['A8', 'B8']]

for e in data:
if randint(0, 2) == 0:
e[0], e[1] = e[1], e[0]
``````
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.