SymPy – произвольное количество символов

Я кодирую функцию, которая решает произвольное число одновременных уравнений. Количество уравнений задается одним из параметров функции, и каждое уравнение построено из числа символов – столько символов, сколько есть уравнений. Это означает, что я не могу просто закодировать уравнения или даже символы, необходимые для объединения уравнений; функция должна иметь возможность обрабатывать любое количество уравнений. Итак, мой вопрос: как мне составить список символов?

У меня есть одно возможное решение, но мой кишок говорит мне, что он не будет очень эффективным. Пожалуйста, дайте мне знать, если есть лучший способ сделать это.

Я новичок в SymPy, и я все еще чувствую свой путь. Насколько я вижу, символы должны быть определены строкой. Поэтому я могу создать ряд строк, добавив добавочное число к букве (например, «t0», «t1» и т. Д.), Добавьте их в список и затем создайте символы, используя эти строки в качестве параметров. Эти символы сами будут храниться в списке и будут использоваться для создания уравнений.

def solveEquations(numEquations): symbolNameList = [] symbolList = [] equationList = [] for i in range(numEquations): name = 't' + str(i) symbolNameList.append(name) symbolList.append(Symbol(name)) for i in range(numEquations): equation = 0 for sym in symbolList: equation += sym ** i # Or whatever structure the equation needs equationList.append(equation) #Then go on to solve the equations... 

Это лучший способ сделать это, или есть более эффективный подход?

5 Solutions collect form web for “SymPy – произвольное количество символов”

Функция symbols может использоваться для легкого создания списков символов

 In [1]: symbols('a0:3') Out[1]: (a₀, a₁, a₂) In [2]: numEquations = 15 In [3]: symbols('a0:%d'%numEquations) Out[3]: (a₀, a₁, a₂, a₃, a₄, a₅, a₆, a₇, a₈, a₉, a₁₀, a₁₁, a₁₂, a₁₃, a₁₄) 

numbered_symbols("t") вернет генератор, который генерирует t0 , t1 , t2 и т. д. Вы можете использовать параметр start для выбора другого стартового значения. И если вы хотите использовать фиктивные переменные, используйте numbered_symbols("t", cls=Dummy) .

Ваш подход хорош, хотя нет необходимости хранить имена символов отдельно (вы можете получить доступ к имени символа через его свойство name ).

Кроме того, вы можете выразить создание символа немного более кратко (хотя не более эффективно), например:

 symbolList = map(lambda i: Symbol('t' + str(i)), xrange(numEquations)) 

Однако для вашего случая использования (временные переменные) фиктивные переменные, вероятно, являются способом:

 symbolList = map(Dummy, xrange(numEquations)) 

Это не более эффективно, так как внутри класса Dummy также используется счетчик для создания уникальных имен, но он немного чище и понятнее.

Вы можете создать подкласс dict который автоматически возвращает Symbols :

 import sympy as sym class SymDict(dict): # http://stackoverflow.com/a/3405143/190597 def __missing__(self, key): self[key]=sym.Symbol(key) return self[key] def solveEquations(numEquations): symbol = SymDict() symbolList = ['t'+str(i) for i in range(numEquations)] equationList = [sum(symbol[s]**i for s in symbolList) for i in range(numEquations)] print(equationList) solveEquations(3) # [3, t0 + t1 + t2, t0**2 + t1**2 + t2**2] 

Используя locals() и понимание словаря, вы можете итеративно генерировать оба символа и локальные переменные python с похожим именем. Например:

 >>> symbols_dict = dict(('a%d'%k, symbols('a%d'%k)) for k in range(3)) >>> locals().update(symbols_dict) 

Проверка работы:

 >>> print(expand((a0+a2)*(a0+a1**2))) a0**2 + a0*a1**2 + a0*a2 + a1**2*a2 
Python - лучший язык программирования в мире.