Shuffle two lists in the same order in python

為{幸葍}努か 提交于 2019-12-06 09:12:29
Jonas Lindeløv

This question has been answered here and here. I particularly like the following for its syntactic simplicity

randomizedItems = map(items.__getitem__, indices)

For a complete working example, see code below. Note that I've changed quite a bit to make the code much shorter, cleaner and faster. See comments.

# 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'])

Another way to randomize the images while maintaining the pairing is something you'd probably do anyway sometime: put them together in a list of dictionaries, where each dict represents a trial. So rather than the two map lines, do:

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

Try printing the trial list (print trialList) to see what it looks like. And then loop over trials:

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.
Spice

The simplest way I can think to handle this is use a separate list for indices, and shuffle it instead.

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

I would create an array of numbers, shuffle it and sort the image lists both according to the shuffled numbers.

So both lists are shuffled in the same way.

    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)
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!