Create lists which cycle at the required rates to get balancing across their respective entries:
SOAs = [1.0, 2.0] * 2 # entries cycle quickly
[1, 2, 1, 2]
colours = ['red'] * 2 + ['blue'] * 2 # entries cycle slower
['red', 'red', 'blue', 'blue']
Zip them together in a single list:
condition_pairs = list(zip(colours, SOAs))
[('red', 1), ('red', 2), ('blue', 1), ('blue', 2)]
More usefully you might want the trial conditions in a list of dictionaries so you can refer to attributes by name, so do something like this:
trials = [{'colour':c[0], 'SOA':c[1]} for c in zip(colours, SOAs)]
[{'colour': 'red', 'SOA': 1},
{'colour': 'red', 'SOA': 2},
{'colour': 'blue', 'SOA': 1},
{'colour': 'blue', 'SOA': 2}]
To randomise:
from numpy.random import shuffle
shuffle(trials)
e.g.
for trial in trials:
some_stimulus.colour = trial['colour']
some_stimulus.draw()
win.flip()
core.wait(trial['SOA'])