Python石头剪刀布游戏中permutations引发索引越界错误排查
石头剪刀布游戏的索引越界问题
这是我编写的第二个Python代码,是用于学习练习的石头剪刀布游戏。我尝试使用permutations模块进行拓展,却在if语句处触发了「Index Out of range Error」。
代码如下:
from itertools import permutations import random options = ["rock","scissors","paper"] perm = permutations(options,2) x = 0 while x <= 10: def get_choices(): print("Please choose enter a choice (Rock, Paper, Scissors): ",end="") player_choice = input("") computer_choice = random.choice(options) #choice in random is an Atribute and note related to function naming choices = [player_choice, computer_choice] return choices result = get_choices() print("Results Player Vs PC",result) #print(list(perm)[1]) #for testing if result == list(perm)[0]: print("You've won") elif result == list(perm)[1]: print("You've lost") elif result == list(perm)[2]: print("You've lost") elif result == list(perm)[3]: print("You've won") elif result == list(perm)[4]: print("You've Won") elif result == list(perm)[5]: print("You've lost") else: print("Draw")
报错提示list(perm)[0]索引越界,但打印perm的列表时能正常显示所有排列结果,请问这是为什么?
问题原因
permutations()返回的是迭代器对象,不是列表。迭代器的核心特性是只能被遍历一次:第一次调用list(perm)时,会把迭代器里的所有元素取出来转成列表,此时迭代器就被耗尽了。之后再调用list(perm),得到的就是空列表,自然会触发索引越界错误。
举个例子,第一次执行list(perm)[0]时,迭代器已经被掏空,后续的list(perm)[1]、list(perm)[2]等操作都是在空列表里找元素,肯定会报错。
修复方案
1. 提前将迭代器转为列表保存
在循环外面就把perm转成列表,这样每次循环都能重复访问里面的元素,不会出现迭代器耗尽的问题:
from itertools import permutations import random options = ["rock","scissors","paper"] # 提前把迭代器转成列表,后续直接用这个列表 perm_list = list(permutations(options,2)) # 把函数定义移到循环外,没必要每次循环重新定义 def get_choices(): print("Please choose enter a choice (Rock, Paper, Scissors): ", end="") player_choice = input("").lower() # 转小写,避免大小写不匹配导致的判断错误 computer_choice = random.choice(options) choices = [player_choice, computer_choice] return choices x = 0 while x <= 10: result = get_choices() print("Results Player Vs PC", result) if result == perm_list[0]: print("You've won") elif result == perm_list[1]: print("You've lost") elif result == perm_list[2]: print("You've lost") elif result == perm_list[3]: print("You've won") elif result == perm_list[4]: print("You've Won") elif result == perm_list[5]: print("You've lost") else: print("Draw") x += 1 # 必须加这句,否则循环会无限执行
2. 额外优化说明
- 把
get_choices()函数移到循环外,原代码每次循环都重新定义函数,完全没必要 - 给用户输入转小写,避免用户输入"Rock"或"ROCK"时,和列表里的小写元素不匹配导致误判为平局
- 循环里添加
x += 1,原代码没有这一步,会陷入无限循环
内容的提问来源于stack exchange,提问作者Yazmoorish
相关产品推荐
相关产品推荐

