Перемешать два списка в том же порядке в Python

У меня есть вопрос о тасовании, но сначала вот мой код:

from psychopy import visual, event, gui
import random, os
from random import shuffle
from PIL import Image
import glob
a = glob.glob("DDtest/targetimagelist1/*")
b = glob.glob("DDtest/distractorimagelist1/*")
target = a
distractor = b
pos1 = [-.05,-.05]
pos2 = [.05, .05]

shuffle(a)
shuffle(b)

def loop_function_bro():
    win = visual.Window(size=(1280, 800), fullscr=True, screen=0, monitor='testMonitor', color=[-1,-1,-1], colorSpace='rgb')
        distractorstim = visual.ImageStim(win=win,
        image= distractor[i], mask=None,
        ori=0, pos=pos1, size=[0.5,0.5],
        color=[1,1,1], colorSpace='rgb', opacity=1,
        flipHoriz=False, flipVert=False,
        texRes=128, interpolate=True, depth=-1.0)

    targetstim= visual.ImageStim(win=win,
        image= target[i], mask=None,
        ori=0, pos=pos2, size=[0.5,0.5],
        color=[1,1,1], colorSpace='rgb', opacity=1,
        flipHoriz=False, flipVert=False,
        texRes=128, interpolate=True, depth=-2.0)

    distractorstim.setAutoDraw(True)
    targetstim.setAutoDraw(True)
    win.flip()
    event.waitKeys(keyList = ['space'])

for i in range (2):  
    loop_function_bro()

Этот код случайным образом перемешивает кучу изображений и отображает их. Тем не менее, я хотел бы, чтобы перемешать изображения в том же порядке, чтобы оба списка отображались в том же случайном порядке. Есть ли способ сделать это?

Ура:)

4 ответа

Решение

На этот вопрос ответили здесь и здесь. Мне особенно нравится следующее за его синтаксическую простоту

randomizedItems = map(items.__getitem__, indices)

Для полного рабочего примера, см. Код ниже. Обратите внимание, что я немного изменился, чтобы сделать код намного короче, чище и быстрее. Смотрите комментарии.

# Import stuff. This section was simplified.
from psychopy import visual, event, gui  # gui is not used in this script
import random, os, glob
from PIL import Image

pos1 = [-.05,-.05]
pos2 = [.05, .05]

# import two images sequences and randomize in the same order
target = glob.glob("DDtest/targetimagelist1/*")
distractor = glob.glob("DDtest/distractorimagelist1/*")
indices = random.sample(range(len(target)), len(target))  # because you're using python 2
target = map(target.__getitem__, indices)
distractor = map(distractor.__getitem__, indices)

# Create window and stimuli ONCE. Think of them as containers in which you can update the content on the fly.
win = visual.Window(size=(1280, 800), fullscr=True, screen=0, monitor='testMonitor', color=[-1,-1,-1])  # removed a default value
targetstim = visual.ImageStim(win=win, pos=pos2, size=[0.5,0.5])
targetstim.autoDraw = True
distractorstim = visual.ImageStim(win=win, pos=pos1, size=[0.5,0.5])  # removed all default values and initiated without an image. Set autodraw here since you didn't seem to change it during runtime. But feel free to do it where you please.
distractorstim.autoDraw = True

# No need to pack in a function. Just loop immediately. Rather than just showing two stimuli, I've set it to loop over all stimuli.
for i in range(len(target)):
    # set images. OBS: this may take some time. Probably between 20 and 500 ms depending mainly on image dimensions. Smaller is faster. It's still much faster than generating a full Window/ImageStim each loop though.
    distractorstim.image = distractor[i]
    targetstim.image = target[i]

    # Display and wait for answer
    win.flip()
    event.waitKeys(keyList = ['space'])

Другой способ рандомизации изображений при сохранении сопряжения - это то, что вы, вероятно, когда-нибудь когда-нибудь сделаете: объедините их в список словарей, где каждый диктовку представляет испытание. Так что вместо двух map линии, сделайте:

trialList = [{'target':target[i], 'distractor':distractor[i]} for i in indices]

Попробуйте распечатать пробный список (print trialList) чтобы увидеть, как это выглядит. А затем переберите испытания:

for trial in trialList:
    # set images.
    targetstim.image = trial['target']
    distractorstim.image = trial['distractor']

    # Display and wait for answer. Let's record reaction times in the trial, just for fun.
    win.flip()
    response = event.waitKeys(keyList = ['space'], timeStamped=True)
    trial['rt'] = response[0][1]  # first answer, second element is rt.

Простейший способ справиться с этим - использовать отдельный список для индексов и вместо этого перемешать его.

indices = list(xrange(len(a)))  # Or just range(len(a)) in Python 2
shuffle(indices)

Я хотел бы создать массив чисел, перемешать его и отсортировать списки изображений в соответствии с перемешанными числами.

Таким образом, оба списка перетасовываются одинаково.

    data1=[foo bar foo]
    data2=[bar foo bar]
    data3=[foo bar foo]
    alldata=zip((data1,data2,data3))
# now do your shuffling on the "outside" index of alldata then
    (data1shuff,data2shuff,data3shuff) = zip(*alldata)
Другие вопросы по тегам