Python 2.7.3中使用eval和list来求解数学表达式

在 Python 2.7.3 中,eval() 函数可以用来执行字符串形式的 Python 表达式,并返回表达式的值。这是一个在进行数学计算时非常有用的功能,尤其是当你需要处理由用户输入的或动态生成的表达式时。然而,使用 eval() 时需要特别小心,因为它也可以执行任意代码,可能导致安全问题。

这里是一个简单的例子,展示如何使用 eval() 来计算数学表达式,并且介绍如何安全地限制 eval() 所执行代码的环境。

1、问题背景

在 Python 2.7.3 中,我需要创建一个函数来进行以下操作:

  • 创建一个数学问题并将其作为字符串输出,其中主题是运算顺序。
  • 作为输出的第二部分,输出此问题的正确答案。
  • 作为其余输出,输出错误答案,但如果更改运算顺序(例如让减法先于乘法),则可以达到这些答案。

该函数不需要任何参数,但在问题过程中需要我们进行以下导入:

arduino 复制代码
import random
from random import choice

这样做是为了生成随机整数作为任何问题的数字,并选择问题中涉及的操作,例如 *,/,+,-。

2、解决方案

有两种解决这个问题的方法:

方法一

  1. 我通过交替将整数和操作添加到字符串来制作一个字符串(因此以整数结尾),然后在最后在字符串的某些位置加上括号。
  2. 我使用 eval() 来评估字符串并因此提供正确的答案。
  3. 我通过在不同的地方插入括号来制作该字符串的其他版本,以便返回不同的答案,然后我使用 eval() 对其进行求值以找到其他答案。

方法二

这类似于方法一,但将元素放入列表中。

  1. 将运算顺序提供为列表作为输入,例如正确的运算顺序为 [*,(,/),(+,-)],然后找到这些运算在列表中的位置,并对左右的整数执行运算,删除列表的 3 个部分,并用我们找到的答案替换它们。我们对整个列表的所有操作执行此操作,使用重复。
  2. 我通过输入一个运算顺序方面不同的列表来简单地获得不同的答案,从而使寻找错误答案的步骤变得更容易。

代码例子

方法一

python 复制代码
import random
from random import choice
​
def create_question():
  """Creates a math question as a string."""
​
  # Generate random integers and operations.
  integers = [random.randint(1, 10) for _ in range(5)]
  operations = choice(['+', '-', '*', '/'])
​
  # Create a string representation of the question.
  question = ""
  for i in range(len(integers)):
    question += str(integers[i])
    if i < len(integers) - 1:
      question += operations
​
  # Add parentheses to the string in random places.
  for _ in range(random.randint(1, 3)):
    index = random.randint(0, len(question) - 1)
    question = question[:index] + '(' + question[index:]
​
  return question
​
def evaluate_question(question):
  """Evaluates a math question string and returns the answer."""
​
  return eval(question)
​
def find_incorrect_answers(question):
  """Finds incorrect answers to a math question string."""
​
  incorrect_answers = []
​
  # Try adding parentheses to the string in different places.
  for i in range(len(question)):
    if question[i] in ['+', '-', '*', '/']:
      new_question = question[:i] + '(' + question[i:] + ')'
      incorrect_answers.append(evaluate_question(new_question))
​
  # Try changing the order of operations.
  for operation in ['+', '-', '*', '/']:
    new_question = question.replace(operation, '')
    incorrect_answers.append(evaluate_question(new_question))
​
  return incorrect_answers
​
# Test the function.
question = create_question()
print("Question:", question)
correct_answer = evaluate_question(question)
print("Correct answer:", correct_answer)
incorrect_answers = find_incorrect_answers(question)
print("Incorrect answers:", incorrect_answers)

方法二

python 复制代码
import random
from random import choice
​
def create_question():
  """Creates a math question as a string."""
​
  # Generate random integers and operations.
  integers = [random.randint(1, 10) for _ in range(5)]
  operations = choice(['+', '-', '*', '/'])
​
  # Create a list representation of the question.
  question = []
  for i in range(len(integers)):
    question.append(integers[i])
    if i < len(integers) - 1:
      question.append(operations)
​
  return question
​
def evaluate_question(question):
  """Evaluates a math question list and returns the answer."""
​
  # Find the indices of the operations.
  operation_indices = [i for i, op in enumerate(question) if op in ['+', '-', '*', '/']]
​
  # Evaluate the question using the correct order of operations.
  while operation_indices:
    # Find the index of the first operation.
    index = operation_indices[0]
​
    # Perform the operation.
    operation = question[index]
    left_operand = question[index - 1]
    right_operand = question[index + 1]
    result = eval(str(left_operand) + operation + str(right_operand))
​
    # Replace the operation and its operands with the result.
    question = question[:index - 1] + [result] + question[index + 2:]
​
    # Update the list of operation indices.
    operation_indices = [i - 1 for i in operation_indices if i > index]
​
  # Return the final result.
  return question[0]
​
def find_incorrect_answers(question):
  """Finds incorrect answers to a math question list."""
​
  incorrect_answers = []
​
  # Try changing the order of operations.
  for operation in ['+', '-', '*', '/']:
    new_question = question.copy()
​
    # Find the indices of the operations.
    operation_indices = [i for i, op in enumerate(new_question) if op in ['+', '-', '*', '/']]
​
    # Change the order of operations.
    while operation_indices:
      # Find the index of the first operation.
      index = operation_indices[0]
​
      # Perform the operation.
      operation = new_question[index]
      left_operand = new_question[index - 1]
      right_operand = new_question[index + 1]
      result = eval(str(left_operand) + operation + str(right_operand))
​
      # Replace the operation and its operands with the result.
      new_question = new_question[:index - 1] + [result] + new_question[index + 2:]
​
      # Update the list of operation indices.
      operation_indices = [i - 1 for i in operation_indices if i > index]
​
    # Evaluate the question.
    incorrect_answers.append(evaluate_question(new_question))
​
  return incorrect_answers
​
# Test the function.
question = create_question()
print("Question:", question)
correct_answer = evaluate_question(question)
print("Correct answer:", correct_answer)
incorrect_answers = find_incorrect_answers(question)
print("Incorrect answers:", incorrect_answers)

虽然 eval() 是一个强大的工具,能够动态执行字符串形式的代码,但它的使用需要谨慎,尤其是在处理用户输入的数据时。确保限制 eval() 的执行环境可以帮助防止潜在的安全风险。此外,对于复杂的数学表达式解析和计算,考虑使用像 NumPySymPy 这样的专门库,这些库提供了更强大、更安全的数学运算支持。

相关推荐
一斤代码2 小时前
vue3 下载图片(标签内容可转图)
前端·javascript·vue
中微子2 小时前
React Router 源码深度剖析解决面试中的深层次问题
前端·react.js
光影少年2 小时前
从前端转go开发的学习路线
前端·学习·golang
中微子3 小时前
React Router 面试指南:从基础到实战
前端·react.js·前端框架
3Katrina3 小时前
深入理解 useLayoutEffect:解决 UI "闪烁"问题的利器
前端·javascript·面试
前端_学习之路4 小时前
React--Fiber 架构
前端·react.js·架构
伍哥的传说4 小时前
React 实现五子棋人机对战小游戏
前端·javascript·react.js·前端框架·node.js·ecmascript·js
qq_424409194 小时前
uniapp的app项目,某个页面长时间无操作,返回首页
前端·vue.js·uni-app
我在北京coding4 小时前
element el-table渲染二维对象数组
前端·javascript·vue.js
布兰妮甜4 小时前
Vue+ElementUI聊天室开发指南
前端·javascript·vue.js·elementui