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 simplify your code a lot:
- 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.
- 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']]
You can use random.shuffle
, this function can shuffle list inplace.
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]