Например, я хочу найти все пять корней многочлена x**3 * (x - 3)**2
.
Команда sympy solve
находит 0
и 3
:
from sympy import *
x = symbols ('x')
solve (x**3 * (x - 3)**2)
[0, 3]
Согласно фундаментальной теореме алгебры, я надеялся, что solve
учтет кратность корней и вернет что-то вроде
[0, 0, 0, 3, 3]
К сожалению, я не смог найти ни одного параметра, который убедил бы solve
или другие решатели, такие как solveset
, nonlinsolve
и nsolve
, вернуть список из пяти элементов. К счастью, roots
sympy возвращает словарь с указанием кратности:
r = roots (x**3 * (x - 3)**2); r
{3: 2, 0: 3}
Есть ли простой способ преобразовать этот словарь в желаемый список из пяти элементов? я придумал
l = []
for k, v in r.items ():
for m in range (v):
l.append (k)
l
[3, 3, 0, 0, 0]
но я чувствую, что должен быть более элегантный способ...
Немного более элегантное решение:
a = []
[a.extend([k]*v) for k, v in r.items()]
print(a)
Такие вещи довольно рано рассматриваются в официальном руководстве: docs.python.org/3/учебник.
[n]*m
создает список из m элементов, заполненный элементами со значением n. Например, [2]*5 = [2, 2, 2, 2, 2]
. В соответствии с этим (stackoverflow.com/questions/37234887/…) это можно было бы назвать «повторением последовательности», но это в значительной степени перегруженный оператор умножения.
Вы также можете использовать двойную петлю for
, как в a = [k for k, v in r.items() for _ in range(v)]
. Или, короче, a = [k for k in r for _ in range(r[k])]
Используйте аргумент multiple
для roots
:
In [91]: roots(x**3 * (x - 3)**2)
Out[91]: {0: 3, 3: 2}
In [92]: roots(x**3 * (x - 3)**2, multiple=True)
Out[92]: [0, 0, 0, 3, 3]
https://docs.sympy.org/latest/modules/polys/reference.html#sympy.polys.polyroots.roots
Тонкое решение! Поскольку я новичок в python, я не знал, что вы можете создавать несколько записей в списке с помощью
[k]*v
. Как вы называете такую конструкцию и где я могу узнать об этом?