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 这样的专门库,这些库提供了更强大、更安全的数学运算支持。

相关推荐
雪碧聊技术5 分钟前
深入解析Vue中v-model的双向绑定实现原理
前端·javascript·vue.js·v-model
快起来别睡了7 分钟前
手写 Ajax 与 Promise:从底层原理到实际应用
前端
打不着的大喇叭1 小时前
uniapp的光标跟随和打字机效果
前端·javascript·uni-app
无我Code1 小时前
2025----前端个人年中总结
前端·年终总结·创业
程序猿阿伟1 小时前
《前端路由重构:解锁多语言交互的底层逻辑》
前端·重构
Sun_light1 小时前
6个你必须掌握的「React Hooks」实用技巧✨
前端·javascript·react.js
爱学习的茄子1 小时前
深度解析JavaScript中的call方法实现:从原理到手写实现的完整指南
前端·javascript·面试
莫空00001 小时前
Vue组件通信方式详解
前端·面试
呆呆的心1 小时前
揭秘 CSS 伪元素:不用加标签也能玩转出花的界面技巧 ✨
前端·css·html
susnm1 小时前
Dioxus 与数据库协作
前端·rust