在 python 中以相同的顺序随机播放两个列表

Shuffle two lists in the same order in 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()

此代码随机排列一堆图像并显示它们。但是,我希望它以相同的顺序随机播放图像,以便两个列表以相同的随机顺序显示。有没有办法做到这一点?

干杯,:)

我会创建一个数字数组,将其打乱并根据打乱的数字对图像列表进行排序。

所以两个列表都以相同的方式洗牌。

我认为处理此问题的最简单方法是为索引使用单独的列表,shuffle 而是使用它。

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)

此问题已得到解答 here and here。我特别喜欢以下句法简单

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.