2

I am creating an conditioning experiment with three conditions (0,1,2) and need to pseudo-randomize condition order. I need a randomize list with each condition occurring only 2 times in a row. Here how I tried to achieve it. The code is running but it takes an eternity...

Any ideas why this code is not working well and any different approaches to solve the problem?

#create a list with 36 values
types  = [0] * 4 + [1] * 18 + [2]*14 #0=CS+ ohne Verstärkung; 1 = CS-, 2=CS+     mit shock

#random.shuffle(types)

while '1,1,1' or '2,2,2' or '0,0,0' in types:
    random.shuffle(types)
else: print(types)

Thank you in advance! Martina

2
  • exactly two times in a row or at most two times in a row? Commented Mar 24, 2017 at 19:00
  • another similar question: stackoverflow.com/questions/3313590/… Commented Mar 24, 2017 at 19:19

2 Answers 2

1

Your loop has several problems. First while '1,1,1' or '2,2,2' or '0,0,0' in types: is the same as while ('1,1,1') or ('2,2,2') or ('0,0,0' in types):. Non-zero strings are always True so your condition is always true and the while never stops. Even if it did, types is a list of integers. '0,0,0' is a string and is not an element of the list.

itertools.groupby is a good tool to solve this problem. Its an iterator that is designed to group a sequence into subiterators. You can use it to see if any clusters of numbers are too long.

import random
import itertools

#create a list with 36 values
types  = [0] * 4 + [1] * 18 + [2]*14 #
print(types)

while True:
    random.shuffle(types)
    # try to find spans that are too long
    for key, subiter in itertools.groupby(types):
        if len(list(subiter)) >= 3:
            break # found one, staty in while 
    else:
        break # found none, leave while

print(types)
Sign up to request clarification or add additional context in comments.

1 Comment

Really cool! It totally solved my problem! Never heard of the itertools module before... Learnt a lot! ;)
1
while '1,1,1' or '2,2,2' or '0,0,0' in types:
    random.shuffle(types)

evaluates as:

while True or True or '0,0,0' in types:
    random.shuffle(types)

and short-circuits at while True

Instead, use: any() which returns True if any of the inner terms are True

Additionally, your types is numbers and you're comparing it to strings:

>>> types
[0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]

so you need to map those numbers to a string which can be compared:

>>> ','.join(map(str, types))
'0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2'

Try:

while any(run in ','.join(map(str, types)) for run in ['0,0,0', '1,1,1', '2,2,2']):
    random.shuffle(types)

>>> types
[1, 2, 1, 2, 1, 2, 1, 1, 0, 2, 0, 1, 2, 1, 1, 2, 1, 2, 1, 2, 2, 1, 1, 2, 0, 2, 1, 1, 0, 2, 1, 1, 2, 2, 1, 1]

2 Comments

Thanks! That is a great solution as well! As a total python beginner, I do not really understand what's the map-function is doing. Does it apply "str" to every element in the list types? So is it iterating over all items or does a map function works differently?
@MartinaTakeaway Yes, map() applies the given function to every item in the supplied iterator.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.