# Impossible to sort Sym elements

**URL:** <https://discourse.julialang.org/t/impossible-to-sort-sym-elements/51810>\
**Category:** General Usage\
**Tags:** question, sort, sympy\
**Created:** [December 14, 2020, 4:49pm UTC](https://discourse.julialang.org/t/impossible-to-sort-sym-elements/51810 "2020-12-14T16:49:02Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![fms-1988](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fms-1988/32/20275_2.png) [@fms-1988](https://discourse.julialang.org/u/fms-1988)\
**Post date:** [December 14, 2020, 4:49pm UTC](https://discourse.julialang.org/t/impossible-to-sort-sym-elements/51810/1 "2020-12-14T16:49:02Z")

</div>

I’m trying to order elements (Sym) from a Tuple. I’ve tried several codes but nothing works.

I will be grateful if anyone can help.

```julia
using SymPy
using LinearAlgebra

a1 = [Sym("a_$i^$j") for i=1 for j=1:2]
a2 = [Sym("a_$i^$j") for i=2 for j=1:2] 
A = [a1,a2] # conjunto de todas as ações
S = vec(collect(Base.product(A...))) #Cartesian product

SymPy.sort!(S, by = x -> S[1])

```

---

<div class="post-metadata">

**Author:** ![contradict](https://avatars.discourse-cdn.com/v4/letter/c/ac91a4/32.png) [@contradict](https://discourse.julialang.org/u/contradict)\
**Post date:** [December 14, 2020, 5:31pm UTC](https://discourse.julialang.org/t/impossible-to-sort-sym-elements/51810/2 "2020-12-14T17:31:32Z")

</div>

Is that just a typo? `S[1]` should be `x[1]`:

```julia
SymPy.sort!(S, by = x -> x[1])

```

---

<div class="post-metadata">

**Author:** ![fms-1988](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fms-1988/32/20275_2.png) [@fms-1988](https://discourse.julialang.org/u/fms-1988)\
**Post date:** [December 14, 2020, 6:46pm UTC](https://discourse.julialang.org/t/impossible-to-sort-sym-elements/51810/3 "2020-12-14T18:46:17Z")

</div>

You are right, this is the most correct way.  
i tried that too.  
But the result is still not the desired one:

8-element Array{Tuple{Sym,Sym,Sym},1}:  
(a\_1^1, a\_2^1, a\_3^1)  
(a\_1^2, a\_2^1, a\_3^1)  
(a\_1^1, a\_2^2, a\_3^1)  
(a\_1^2, a\_2^2, a\_3^1)  
(a\_1^1, a\_2^1, a\_3^2)  
(a\_1^2, a\_2^1, a\_3^2)  
(a\_1^1, a\_2^2, a\_3^2)  
(a\_1^2, a\_2^2, a\_3^2)

The result I want is:

(a\_1^1, a\_2^1, a\_3^1)  
(a\_1^1, a\_2^1, a\_3^2)  
(a\_1^1, a\_2^2, a\_3^1)  
(a\_1^1, a\_2^2, a\_3^2)  
(a\_1^2, a\_2^1, a\_3^1)  
(a\_1^2, a\_2^1, a\_3^2)  
(a\_1^2, a\_2^2, a\_3^1)  
(a\_1^2, a\_2^2, a\_3^2)

---

<div class="post-metadata">

**Author:** ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)\
**Post date:** [December 14, 2020, 6:51pm UTC](https://discourse.julialang.org/t/impossible-to-sort-sym-elements/51810/4 "2020-12-14T18:51:15Z")

</div>

There is no order defined on the Julia representation of a Sym object, but you can workaround with e.g.

```julia
sort(S, by = x -> String(Symbol(x[1])) )

```

---

<div class="post-metadata">

**Author:** ![fms-1988](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fms-1988/32/20275_2.png) [@fms-1988](https://discourse.julialang.org/u/fms-1988)\
**Post date:** [December 14, 2020, 7:14pm UTC](https://discourse.julialang.org/t/impossible-to-sort-sym-elements/51810/5 "2020-12-14T19:14:16Z")

</div>

perfect  
thank you

---

<div class="post-metadata">

**Author:** ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)\
**Post date:** [December 15, 2020, 5:16pm UTC](https://discourse.julialang.org/t/impossible-to-sort-sym-elements/51810/6 "2020-12-15T17:16:11Z")

</div>

`sort` also accepts a keyword argument `lt` (standing for less-than) which defaults to `isless`. Since `isless` doesn’t seem to be useful for `Sym`s, you can set a comparison manually. If you want it to follow the string order, you can do:

```julia
sort(S, by = first, lt = (x, y) -> string(x) < string(y))

```

You can also adjust the `by` argument accordingly, as suggested above:

```julia
sort(S, by = string ∘ first)

```

---

<div class="post-metadata">

**Author:** ![fms-1988](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fms-1988/32/20275_2.png) [@fms-1988](https://discourse.julialang.org/u/fms-1988)\
**Post date:** [December 15, 2020, 6:58pm UTC](https://discourse.julialang.org/t/impossible-to-sort-sym-elements/51810/7 "2020-12-15T18:58:07Z")

</div>

thanks @tomerarnon ,

The code, written in this way, is more understandable. But it does not allow to order columns 2 and 3.

I managed to sort all the columns using the following code:

```julia
S1 = sort(S, by = a -> String(Symbol(a[3])))
S2 = sort(S1, by = a -> String(Symbol(a[2])))
S3 = sort(S2, by = a -> String(Symbol(a[1])))

```

8-element Array{Tuple{Sym,Sym,Sym},1}:  
(a\_1^1, a\_2^1, a\_3^1)  
(a\_1^1, a\_2^1, a\_3^2)  
(a\_1^1, a\_2^2, a\_3^1)  
(a\_1^1, a\_2^2, a\_3^2)  
(a\_1^2, a\_2^1, a\_3^1)  
(a\_1^2, a\_2^1, a\_3^2)  
(a\_1^2, a\_2^2, a\_3^1)  
(a\_1^2, a\_2^2, a\_3^2)

---

<div class="post-metadata">

**Author:** ![Jeff\_Emanuel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeff_emanuel/32/15440_2.png) [@Jeff\_Emanuel](https://discourse.julialang.org/u/Jeff_Emanuel)\
**Post date:** [December 15, 2020, 7:20pm UTC](https://discourse.julialang.org/t/impossible-to-sort-sym-elements/51810/8 "2020-12-15T19:20:49Z")

</div>

> [@fms-1988](#):
>
> But it does not allow to order columns 2 and 3.

It does like this

```julia
sort(S, lt = (x, y) -> string(x[1]) < string(y[1]) || string(x[1])==string(y[1]) && string(x[2]) < string(y[2]) || string(x[2])==string(y[2]) && string(x[3]) < string(y[3]))

```

and it also doesn’t require a stable sort algorithm that applying sort multiple times does.

You could simplify and generalize with reduce or a comprehension.

---

<div class="post-metadata">

**Author:** ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)\
**Post date:** [December 15, 2020, 9:20pm UTC](https://discourse.julialang.org/t/impossible-to-sort-sym-elements/51810/9 "2020-12-15T21:20:16Z")

</div>

The way you used is fine, but note that you can just use `string(...)`, rather than `String(Symbol(...))` as I did in my second example.

However, just to demonstrate that you _can_ in fact sort by any column:

```julia
# with `lt`
sort(S, by = x->x[2], lt = (x, y) -> string(x) < string(y))

# or using composition in `by`
sort(S, by = string ∘ (x -> x[2]))

```

So anything is possible 😉

Also, it is now apparent that what you want is simply:

```julia
sort(S, by = string)

```

which will sort the entries in lexicographic order of their strings, which in this case will sort by first character, then second character, then third, and so on. So if your variables are named as you’ve shown, this will work.

---

<div class="post-metadata">

**Author:** ![fms-1988](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fms-1988/32/20275_2.png) [@fms-1988](https://discourse.julialang.org/u/fms-1988)\
**Post date:** [December 19, 2020, 10:55am UTC](https://discourse.julialang.org/t/impossible-to-sort-sym-elements/51810/10 "2020-12-19T10:55:06Z")

</div>

thanks @tomerarnon

This greatly improved my code.
