Bottom Page

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!
Quote
#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

Quote
#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?
Quote
#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

Quote
#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?
Quote
#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

Quote
#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?
Quote
#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.
buran likes this post
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures

Quote
#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!
Quote

Top Page

Possibly Related Threads...
Thread Author Replies Views Last Post
  modifying a list in an expression Skaperen 2 77 Feb-15-2019, 07:57 PM
Last Post: Skaperen
  iterate through a list with comparison of expression Alexandro 6 142 Jan-31-2019, 05:16 PM
Last Post: Scorpio
  assignment: not an operator nor expression, but x=y=z=3 works fine? jefdaels 1 79 Jan-29-2019, 02:19 PM
Last Post: perfringo
  Product expression. jarrod0987 1 124 Dec-13-2018, 11:32 AM
Last Post: buran
  How to assign a found regex expression to a variable Pedroski55 2 243 Nov-24-2018, 07:14 AM
Last Post: Pedroski55
  Random Expression Creator SheeppOSU 2 223 Nov-01-2018, 11:08 PM
Last Post: wavic
  Regular Expression rzbddm 4 276 Oct-30-2018, 04:25 PM
Last Post: stranac
  regular expression question Sanlus 6 338 Aug-04-2018, 06:49 PM
Last Post: volcano63
  Sympy Import error: "unresolved referrence 'sympy' " BoaCoder3 0 269 Jul-27-2018, 12:48 PM
Last Post: BoaCoder3
  "Anything else expression" in Python spedy93 1 388 Jun-21-2018, 06:16 AM
Last Post: wavic

Forum Jump:


Users browsing this thread: 1 Guest(s)