Question: How best to select parts of expression?

54 views
Skip to first unread message

Philipp Janert

unread,
Mar 17, 2026, 7:38:02 PM (6 days ago) Mar 17
to sympy
What is the best method to select parts of an expression 
for further processing, in a reliable way?

Say I have an expression like:

f = h**(2/3) + 3*h**(b + 1/3)*x1 + h**(b + 1)*x1 +
    3*h**(2*b + 2/3)*x1**2 + h**(3*b + 1)*x1**3

and I want all the exponents of h in this sum.

I can get an array of terms, using

terms = f.args

Now, terms[1] == h**(b + 1)*x1

(Note that the order of items in the terms array is 
different from the order in the display of the expression.)

But how do I now pick out the (b+1) in a reliable way?
Do I need to examine terms[1].terms and then search
for the entry containing 'h' (because I can't rely on the 
order of the factors!)? Or is there a better way to do this, 
e.g. a convenience fct, so that I could say something like:

exponentOf(terms[1], h)

I looked through the tutorial and the reference, but did not 
seem to find something applicable.

Best,

Ph. 

Davide Sandona'

unread,
Mar 18, 2026, 6:20:09 AM (6 days ago) Mar 18
to sy...@googlegroups.com
What you are probably looking for is pattern matching.Usually, the `find` method
of a symbolic expression can be used to select patterns. For example,

pows_of_h = list(f.find(lambda t: t.is_Pow and t.base == h))
exponents_of_h = [t.exp for t in pows_of_h]

Then, b+1 is one of the items of `exponents_of_h`.

Davide.


--
You received this message because you are subscribed to the Google Groups "sympy" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sympy+un...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/sympy/e37392c9-a51f-409c-bf48-f3312495daa7n%40googlegroups.com.

Philipp Janert

unread,
Mar 18, 2026, 8:10:31 AM (6 days ago) Mar 18
to sy...@googlegroups.com
Ah, thanks - casting my problem in terms of "pattern matching"
is certainly interesting.

Maybe I can be forgiven for not knowing about the find() method:
I don't think it (or its friends) are mentioned in the tutorial.
And the API documentation does not give away much either:

"find(query, group=False): Find all subexpressions matching a query."

Actually, more interesting than find() are the query predicates.
I don't think is_Pow is documented at all - at least, I could not
find it in the API reference. Are they discussed somewhere; maybe
in context?

I have also just discovered Expr.as_coeff_exponent() (and friends) -
are they what I am looking for? Unfortunately, I don't really
understand their purpose: are they about operating on algebraic
expressions in general, or do they try to guess and extract numeric
expressions specifically?

I am afraid that I am missing something: I can't be the first person
to have this problem. Operating on non-trivial algebraic expressions
always seems to involve identifying and extracting specific bits, yet
I didn't see it discussed anywhere. There must be "best practices". Am
I missing something? Am I thinking about this wrong? (My experience
with CAS is quite limited.) Again: I can't be the first person to have
this problem. ;-)

Best, 

  Ph.

You received this message because you are subscribed to a topic in the Google Groups "sympy" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/sympy/eVGsBtVT1Lg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to sympy+un...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/sympy/CAO%3D1Z0_NEBcb46FgMTYT_6F9vWnmr4D_-0kduwtEPwcRk2eZBQ%40mail.gmail.com.

Davide Sandona'

unread,
Mar 18, 2026, 8:52:46 AM (6 days ago) Mar 18
to sy...@googlegroups.com
I see your point. This is definitely a more advanced and nuanced use of SymPy.
For example, the code that I gave you on the previous reply can be also written as:

all_pows = [t.as_base_exp() for t in f.find(Pow)]
pows_of_h = [t for t in all_pows if t[0] == h]
exponents_of_h = [t[1] for t in pows_of_h]
exponents_of_h

Here, you can see that all I needed to know is Pow, which is documented. [1]
But I see your problem.

> I can't be the first person
> to have this problem. Operating on non-trivial algebraic expressions
> always seems to involve identifying and extracting specific bits, yet
> I didn't see it discussed anywhere. There must be "best practices". Am
> I missing something? Am I thinking about this wrong? 

You are not the only one. However, what you are attempting can be considered as
a niche application of symbolic computing. Many users are just happy that Sympy
computes a result that can be compared against other results using the `equals`
method. Or maybe they just take the results and generate efficient code for 
numerical evaluation using sympy's code generation features. Either way, there may
not be a particular need for going deeper than what `simplify` currently does.

The documentation is definitely lacking a bit in the sense that there are no
examples exploring this topic. However, writing such a section requires time, from
someone that actually uses these topics and can show best practices. This is
a very small subset of people, that's why it hasn't been written yet.

Now, advertisement time: I once wrote a book on this very topic:
"Symbolic Computation with Python and Sympy". Google it. In there you will find
many guided examples about expression manipulation, which is precisely what you
are looking for. It was written after experiencing all the tribulations you are going
through right now and I believe you will find it very helpful.



Davide.


Philipp Janert

unread,
Mar 18, 2026, 10:15:06 AM (5 days ago) Mar 18
to sy...@googlegroups.com
Well, I feel flattered that you regard my problem as "advanced and
nuanced". ;-)

At the same time, it raises an interesting point. I think nobody
on this mailing list really needs SymPy to differentiate sin(x)!
CAS has a place when the algebra becomes so tedious and error-prone
to challenge human capabilities (and patience). But, in my experience,
it is exactly in those cases that CAS run into problems of their own:
sure, they happily generate series expansions to arbitrary order, but
17 pages of gibberish are just not USEFUL.

In my case, it goes a step further, because I don't actually need
the series, I do need the exponents (and other things), for further,
symbolic processing. (Think of it as a generating function.) Hence
the need to pick individual terms and operate on them, in a reliable
fashion. (What I mean by "reliable" is that it must not depend on
arbitrary ordering of terms, or depend on other arbitrary circumstances.)

Back to SymPy.

I quite liked what it did for me on my problem so far, which is
very encouraging! I would like to use it further, hence my questions.

Based on what you say, I will try to write up my experience when I am
done and share it with the group - I think real, non-trivial case studies
are something that is sorely lacking from the CAS world in general (not
just SymPy).

I found your books; I will take a look.

Thanks again.

Best, 

  Ph. 

Reply all
Reply to author
Forward
0 new messages