Random list generation too slow

I am new to coding and first time posting in the forum sorry for any mistakes.

Hi,
I have written the code below for my experiment to generate a list of directions for 2 stimuli presented at the same time.
In the generated list consecutive directions cannot be the same (otherwise there won’t be a direction change in the next trial). Right now code achieves this by shuffling until it finds a list that fulfils the condition, but this process takes 5-20 min. I was wondering if there is a faster way of doing it.

import random as rand

ortho_list= [[0,90], [0,270], [90,0], [90,180], [180,90], [180,270], [270,0], [270, 180]]* 5 #40 trials
rand.shuffle(ortho_list)

double_stim= False
list_ok= False

while list_ok== False:
    for i in range(len(ortho_list)-1):
        #check for consecutive trials
        if ortho_list[i][0]==ortho_list[i+1][0] or ortho_list[i][1]==ortho_list[i+1][1]:
            double_stim= True
            break
    if double_stim== True:
        rand.shuffle(ortho_list) #try a new order
        double_stim= False
    else:
        list_ok= True

print('List of directions [left,right]:')
print(ortho_list)

did you try shuffle(ortho_list) instead of rand.shuffle(ortho_list)
or write the list 5 times instead of multiplying by 5?

neither makes any difference

Would it be acceptable to end up with an extra trial or two at the end of the experiment? If so then you might find my “Randomisation without repetition” online demo useful.

Thank you I will have a look. Meanwhile, I did come up with another way to approach my list generation. I share it here in case it helps anyone

import random as rand

#orthogonal list of directions for an experiment with 2 RDK stimuli on the left and right hemifields. With change direction of movements stay orthogonal to each other
ortho_list= [[0,90], [0,270], [90,0], [90,180], [180,90], [180,270], [270,0], [270, 180]]
rand.shuffle(ortho_list)

directions= [[0,90], [90,0], [180,270], [270,180]] #list cant be empty to be able call the last element
rand.shuffle(directions) #so that every list don't start the same

double_stim= False
list_ok= False

while list_ok== False:
    if len(directions)==(40): #stopping when required no of elements in directions list is reached
        list_ok=True
        print(directions)
    if ortho_list[0][0]==directions[-1][0] or ortho_list[0][1]==directions[-1][1]: #comparing the first [x,y] element of the ortho_list with the last item on the directions list
        double_stim= True
    if double_stim== True:
        rand.shuffle(ortho_list) #Try a new order
        double_stim= False
    else:
        directions.append(ortho_list[0]) #adding the first element of the ortholist to direction list

As far as I can tell in that code there is nothing to equalise the number of presentations of each of the directions.

Also, double_stim will always be true after directions has been appended, which seems inefficient.

Am I right in thinking that both values need to be different, so [0,90] can’t be followed by [0,270]?

You could start with directions = ortho_list[0] to have a fully random starting point instead of restricting thew first four trials to a particular subset.

Your code could therefore be simplified to

import random as rand

#orthogonal list of directions for an experiment with 2 RDK stimuli on the left and right hemifields. With change direction of movements stay orthogonal to each other
ortho_list= [[0,90], [0,270], [90,0], [90,180], [180,90], [180,270], [270,0], [270, 180]]
rand.shuffle(ortho_list)

directions= ortho_list[0]

list_ok= False

while list_ok== False:
    if len(directions)==(40): #stopping when required no of elements in directions list is reached
        list_ok=True
        print(directions)
    rand.shuffle(ortho_list) 
    if ortho_list[0][0]!=directions[-1][0] and ortho_list[0][1]!=directions[-1][1]: #comparing the first [x,y] element of the ortho_list with the last item on the directions list
        directions.append(ortho_list[0]) #adding the first element of the ortholist to direction list

I get the following error:

line 21, in
if ortho_list[0][0]!=directions[-1][0] and ortho_list[0][1]!=directions[-1][1]:
TypeError: ‘int’ object is not subscriptable

Ah. I think this is an issue when directions only has one pair.

Try

import random as rand

#orthogonal list of directions for an experiment with 2 RDK stimuli on the left and right hemifields. With change direction of movements stay orthogonal to each other
ortho_list= [[0,90], [0,270], [90,0], [90,180], [180,90], [180,270], [270,0], [270, 180]]
rand.shuffle(ortho_list)

directions= ortho_list[0]
for Idx in range(7):
    if ortho_list[Idx+1][0]!=directions[0] and ortho_list[Idx+1][1]!=directions[1]:
        directions.append(ortho_list[Idx+1]
        break

list_ok= False

while list_ok== False:
    if len(directions)==(40): #stopping when required no of elements in directions list is reached
        list_ok=True
        print(directions)
    rand.shuffle(ortho_list) 
    if ortho_list[0][0]!=directions[-1][0] and ortho_list[0][1]!=directions[-1][1]: #comparing the first [x,y] element of the ortho_list with the last item on the directions list
        directions.append(ortho_list[0]) #adding the first element of the ortholist to direction list