Python Forum
Get the variables in a sympy expression
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Get the variables in a sympy expression
#1
Hello! I have some equations which I read from a file, and then turn into sympy expressions and I need the variables that appear in each equation. However, for the purpose of my project, I need them in the order in which they appear in the equation. So if the equation is 'a+b*c' I need a program which gives me: a,b,c but not a,c,b or any other combination. Here is what I tried, based on what I found online:

from sympy import *
from sympy.parsing.sympy_parser import parse_expr

eq1 = "x1**(-1.0)*x2" # I normally read this from a file
eq1 = parse_expr(eq1)

print(eq1,eq1.free_symbols)
So, normally, eq1.free_symbols should give me a set of the variables in my expression. However after I ran this code (and other equations, too, with the same problem) several times, I got this output:

x1**(-1.0)*x2 {x1, x2}
x1**(-1.0)*x2 {x1, x2}
x1**(-1.0)*x2 {x2, x1}
x1**(-1.0)*x2 {x2, x1}
x1**(-1.0)*x2 {x2, x1}
x1**(-1.0)*x2 {x2, x1}
x1**(-1.0)*x2 {x1, x2}

So the equation looks fine, but the order of the variables seem to change randomly and this makes it useless for what I need. Can someone tell me how to pick the variables in the order I want (actually any order would be good as long as it doesn't randomly change)? Thank you!
Reply
#2
It looks like free_symbols is a set, which has no intrinsic ordering. If you want a consistent ordering you would need to convert it to a list and sort it (sorted(eq1.free_symbols)).
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#3
(Feb-12-2019, 06:44 AM)ichabod801 Wrote: It looks like free_symbols is a set, which has no intrinsic ordering. If you want a consistent ordering you would need to convert it to a list and sort it (sorted(eq1.free_symbols)).
This doesn't really work. I am getting this error: TypeError: cannot determine truth value of Relational. I assume it is because there is no intrinsic ordering to variables... Also I am a bit confused about this ".free_symbols" function. I understand that mathematically the order doesn't matter in a set. But here the set must be generated somehow (an iterator for example). So shouldn't the generation method at least be consistent?
Reply
#4
It's not a function, it's an attribute. I looked at the documentation and it didn't clearly state that it is a set, so there may be something else going on. What does print(type(eq1.free_symbols)) say?

It doesn't matter if the generation order is consistent. The "order" in the set is determined by the hash function and any hash collisions. The hash function is not guaranteed to be consistent across runs.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#5
(Feb-12-2019, 06:57 AM)ichabod801 Wrote: print(type(eq1.free_symbols))
It says: <class 'set'>

Is there a more consistent way to read the variables in an expression?
Reply
#6
Then the 'Relational' in your error must refer to the elements of the set: x1 and x2. They are apparently not sortable, although I would expect a different error. It doesn't look to be a solvable problem, although I must admit that I have no experience with the sympy module.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#7
(Feb-12-2019, 07:04 AM)ichabod801 Wrote: Then the 'Relational' in your error must refer to the elements of the set: x1 and x2. They are apparently not sortable, although I would expect a different error. It doesn't look to be a solvable problem, although I must admit that I have no experience with the sympy module.
Is there any other package that can do this? It seems like something not too complex to implement. If they are able to find the variables, I assume they go through the expression from left to right, so why not save them in the order they are discovered?
Reply
#8
(Feb-12-2019, 07:07 AM)SJ001 Wrote: why not save them in the order they are discovered?

They probably are, but they are using a set to avoid duplicates of the same symbol. Anyway, I figured it out:

free_syms = sorted(eq1.free_symbols, key = lambda symbol: symbol.name)
Tested it with your code and it works.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#9
(Feb-12-2019, 07:16 AM)ichabod801 Wrote: free_syms = sorted(eq1.free_symbols, key = lambda symbol: symbol.name)
Thanks a lot! It's working!
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  solve ODE with sympy Sergey_Novak 2 903 Dec-02-2023, 12:33 PM
Last Post: Sergey_Novak
  I need assistance with getting sympy to work alex_0 1 1,477 Apr-05-2021, 09:15 PM
Last Post: snippsat
  Pass results of expression to another expression cmdr_eggplant 2 2,238 Mar-26-2020, 06:59 AM
Last Post: ndc85430
  Sympy error "object is not callable" Cupcake 0 4,813 Feb-08-2020, 02:22 AM
Last Post: Cupcake
  Sympy Import error: "unresolved referrence 'sympy' " BoaCoder3 0 2,648 Jul-27-2018, 12:48 PM
Last Post: BoaCoder3
  SymPy - SolveSet Values Plant_Boy 0 2,471 Jan-01-2018, 09:20 PM
Last Post: Plant_Boy
  Sympy symbolic Point shoulddt 0 2,733 Jul-17-2017, 06:07 PM
Last Post: shoulddt
  Sympy Integration Flexico 5 7,430 Dec-07-2016, 07:24 AM
Last Post: micseydel

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020