我正在编写代码以使考试随机化,我需要能够将一个变量随机化,以便从列表中选择一个变量,但不等于另一个变量。
我正在使用eval()评估字符串,并使用exec()在python中定义变量,以便可以从另一个值创建一个值。我遇到的问题是在某些情况下无法识别变量。
就地将变量名和随机化参数作为文本字符串从单独的文件中提取。捕获我的问题的简化的提取代码块是:
import random
def question_randomizer():
randomdef={'w':'random.choice([1,2,3])', 'x':'w+1', 'y':'random.choice([i for i in [w,x] if i not in [2]])', 'z':'random.choice([i for i in [1,2,3] if i not in [w]])'}
for var in randomdef:
variablevalue=eval(randomdef[var])
exec("%s = %s" % (var,variablevalue))
print(var, ' = ', variablevalue)
return
question_randomizer()
exec调用应在代码中定义变量,并且在创建w,x和y时可以正常工作;
w = 2
x = 3
y = 3
但是z总是返回错误
name 'w' is not defined
有人知道如何解决此问题,或者在成功使用w之前为什么会发生此错误?我唯一需要注意的是,我正在尝试避免使用全局变量。
谢谢。
答案 0 :(得分:1)
首先,exec()
和eval()
有点危险,很难正确使用。如果您必须以这种方式解决问题,请改用locals()
函数,然后手动将其添加到局部变量列表中:
locals()[variablename] = variablevalue
但是解决此问题的更好方法可能是使用random.sample()
函数,该函数使您可以从样本中选择任意数量的唯一值:
x1, x2, x4 = random.sample(range(1, 6), 3) # 3 unique values between 1 and 5 inclusive
random.choice(vals)
函数大致等效于random.sample(vals, 1)
。
如果要避免重复值,可以使用set
减法来减少可接受的随机样本的范围:
x3 = random.choice(set(range(1, 6)) - {x1, x2, x4, 2}) # a value between 1 and 5 that is not equal to x1, x2, or x4, or the integer 2