Reputation: 1332
I would like to canonicalize a list of SymPy expressions into lexicographic order. Or, at least, some semblance of it. This was simple on SymPy 0.7.2 and seems to have broken as of...
>>> import sympy
>>> sympy.__version__
'0.7.4.1'
Observe:
>>> f, g = sympy.symbols('f g', cls=sympy.Function)
>>> sorted([f, g])
[f, g]
>>> sorted([g, f])
[f, g]
Cool. I get back lexicographic ordering. Now, if I apply the functions...
>>> x = sympy.symbols('x')
>>> sorted([f(x),g(x)])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/dist-packages/sympy/core/relational.py", line 226, in __nonzero__
raise TypeError("symbolic boolean expression has no truth value.")
TypeError: symbolic boolean expression has no truth value.
...where that TypeError
string has shown up elsewhere from Googling about but I've not been able to discern a workaround.
I see the same message with [f(x), g(x)].sort().
Using set([f(x), g(x)])
won't work in my larger use case because I need to permit duplicates.
Any ideas for a SymPy 0.7.2- and 0.7.4-friendly way to canonicalize a list of SymPy expressions? Playing around a bit sorted([f(x),g(x)], lambda x,y: x.compare(y))
seems to work but feels like a mouthful.
Upvotes: 1
Views: 833
Reputation: 91610
SymPy no longer compares expressions arbitrarily, similar to Python 3. If you want an arbitrary, but consistent order, use the default_sort_key
key function to sorted:
>>> sorted([f(x), g(x)], key=default_sort_key)
[f(x), g(x)]
I believe ordered
does something similar.
Upvotes: 0
Reputation: 19125
Use the 'ordered' function:
>>> list(ordered((g(x),f(x))))
[f(x), g(x)]
It returns a generator -- that's why the result is wrapped with list.
Upvotes: 3