Reputation: 467
here is my code:
import random
from random import shuffle
a = ['a','b','c','d']
b = ['a','b','c','d']
c = ['w','x','y','z']
d = ['w','x','y','z']
indices = random.sample(range(len(a)), len(a))
a = map(a.__getitem__, indices)
b = map(b.__getitem__, indices)
shuffle(c)
shuffle(d)
print a,b,c,d
What this code does is it shuffles a and b in the same order, and shuffles c and d in their own order. What I am trying to do now is making two longer lists composed of a and c, and b and d, and put them in a randomized order. What I want though is for a and b stay the same order across lists. Is there any way to do this? Any help will be greatly appreciated. :)
Edit:
I would like the output to look something like this, where lists a&b correspond and c&d are just randomized independently.
['d','x','w','b','a','y','c','z']
['d','z','y','b','a','x','c','w']
Upvotes: 1
Views: 534
Reputation: 10841
If we shuffle c
and d
first, randomly sampling from the concatenated lists ac
and bd
gives the required result (I'm using Python 3 so the printing requires parentheses):
import random
from random import shuffle
a = ['a','b','c','d']
b = ['a','b','c','d']
c = ['w','x','y','z']
d = ['w','x','y','z']
shuffle(c)
shuffle(d)
# print a,b,c,d
print (a,b,c,d)
ac = a + c
bd = b + d
indices = random.sample(range(len(ac)),len(ac))
ac = list(map(ac.__getitem__, indices))
bd = list(map(bd.__getitem__, indices))
#print ac, bd
print (ac, bd)
Output as follows:
['a', 'b', 'c', 'd'] ['a', 'b', 'c', 'd'] ['x', 'w', 'z', 'y']['y', 'z', 'w', 'x']
['y', 'z', 'c', 'x', 'b', 'w', 'd', 'a'] ['x', 'w', 'c', 'y', 'b', 'z', 'd', 'a']
EDIT:
Thanks to @Jan-Philip Gehrcke who points out that using numpy
indexing (as follows) is much faster when the lists are large:
from random import shuffle
import numpy as np
a = ['a','b','c','d']
b = a[:]
c = ['w','x','y','z']
d = c[:]
shuffle(c)
shuffle(d)
# print a,b,c,d
print (a,b,c,d)
ac = np.array(a + c)
bd = np.array(b + d)
indices = list(range(len(ac)))
shuffle(indices)
ac = ac[indices]
bd = bd[indices]
#print ac, bd
print (ac, bd)
Upvotes: 3
Reputation: 251373
Here is one approach:
a = ['a','b','c','d']
# make b later
c = ['w','x','y','z']
d = ['w','x','y','z']
random.shuffle(a)
random.shuffle(c)
random.shuffle(d)
b = list(a)
x = a + c
random.shuffle(x)
y = []
for item in x:
if item in a:
y.append(b.pop())
else:
y.append(d.pop())
>>> x
['w', 'z', 'b', 'x', 'c', 'd', 'a', 'y']
>>> y
['z', 'y', 'b', 'x', 'c', 'd', 'a', 'w']
If you want a and b to be in the same random order, it's more convenient to just shuffle a, and then make b a copy of it. Then to make the new lists x and y, I first make x by shuffling a + c
, and then build up y by going through x
and adding a member from b
or d
depending on whether the corresponding element of x
is in a
or c
.
This approach assumes that the set of elements in a and b is disjoint from those in c and d. The current version also destroys b and d in the process of making y
, although this could be fixed with a slightly more cumbersome algorithm (keeping track of an index into b
and d
and grabbing elements by index instead of popping).
Upvotes: 1
Reputation: 10913
how about random shuffling c first and then zipping to a ?
import random
a=['a','b','c','d']
b=['a','b','c','d']
c=['w','x','y','z']
d=['w','x','y','z']
random.shuffle(c)
a_c = zip(a,c)
print a_c
[('a', 'y'), ('b', 'z'), ('c', 'x'), ('d', 'w')]
The order of list a is not changed while list c is shuffled randomly. Hope it helps.
Upvotes: 0