我正在编写一个PsychoPy程序(一个用于使用Python进行心理学实验的软件)并且不断获得超出范围的列表索引'错误。问题出现在"如果already_used_values [a] == value:"。我可以看到为什么会发生这种情况的唯一可能原因是因为already_used_values从一个空列表开始;但是,我认为如果列表为空,我通过说返回False来解决这个问题。以下是相关代码供参考。
already_used_values = []#integers in order to sort sounds
sorted_sounds = []#note that these are not 'sorted', they are randomized each time
answer_key = []
def already_used(value):#returns true if value in array of sounds has been used
if len(already_used_values) == 0:
return False
for a in already_used_values:
if already_used_values[a] == value:
return True
return False
def pick_random_value(upLim):
return random.randint(0,upLim-1)
def pick_sound(sound_list):#picks a sound randomly from list_of_sounds
new_value = pick_random_value(len(sound_list))
while(already_used(new_value)):
new_value = pick_random_value(len(sound_list))
already_used_values.append(new_value)
return sound_list[new_value]
def init_sorted_sounds():#appends random sound from list_of_sounds to sorted_sounds
for i in list_of_sounds:
sorted_sounds.append(pick_sound(list_of_sounds))
answer_key = already_used_values
提前谢谢!
答案 0 :(得分:5)
这一行:
for a in already_used_values:
if already_used_values[a] == value:
是您报告的错误的根源。当您说for a in something
时,变量a
会占用something
元素的每个值,而不是每个索引。然而,在下一行中,您使用a
作为索引。例如,如果already_used_values
等于[ 5, 6 ]
,则在第一次迭代时a
取值5,后续行尝试检查明显超出范围的already_used_values[ 5 ]
一个2元素的列表。
很难准确地说出意图,但看起来您的函数already_used
可以简化为单个布尔值表达式new_value in already_used_values
所以行
while(already_used(new_value)):
变为
while( new_value in already_used_values ):
我们摆脱了这个功能。但是,让我们更进一步,并认识到,您可以从已经>的池中随机选择元素,而不是您当前拥有的试错while
循环。 em>在执行选择之前排除使用的值:
remaining_choices = [ x for x in sound_list if x not in already_used_values ]
new_value = random.choice( remaining_choices )
already_used_values.append( new_value )
这样就摆脱了while循环。但我们甚至可以进一步优化,如下面的chthonicdaemon所指出的那样。看起来,最终,你想要用这些代码做的只是找到一个列表的随机重新排序。这可以用一行或两行来完成:
sorted_sounds = list( list_of_sounds ) # make a copy of the original list of sounds
random.shuffle( sorted_sounds ) # randomly reorder the new list in place