# How do I get an ordered list of a symbolic functions arguments?

How can I get a list/tuple of the variables in a symbolic function with the same ordering as when the function was defined? e.g. for the function below I would want (z,t) not the alphabetically ordered (t, z) I get with .variables() of .arguments(). The ordering has to be stored/used somewhere in sage because I can differentiate with respect to z and get D0(z,t) as an answer where the '0' corresponds to 'z'.

sage: var('z,t')
(z, t)
sage: f = function('u',z,t)
sage: print (f)
u(z, t)
sage: f.variables()
(t, z)
sage: f.arguments()
(t, z)
sage: f.diff(z)
D(u)(z, t)
sage: f.diff(t)
D(u)(z, t)

edit retag close merge delete

Sort by » oldest newest most voted I think the .operands() method should do what you want:

sage: var('z,t')
(z, t)
sage: f = function('u',z,t)
sage: f.variables()
(t, z)
sage: f.operands()
[z, t]


We should probably add a reference to operands() in variables()/arguments(). Interested in working up a documentation patch?

We can sanity-check this using a variant of jdc's suggestion:

import string
import random as rnd

def test_one(f):
ops = f.operands()
fops = list(str(op) for op in ops)
sf = str(f)
sops = sf[sf.find('(')+1:sf.find(')')].split(',')
sops = list(sop.strip() for sop in sops)
assert fops == sops

def test_lots():
for c in range(50):
for w in range(1,10):
vv = tuple(var(rnd.choice(string.ascii_letters) + str(randint(0,10))) for _ in range(w))
f = function(*(('u',) + vv))
print f
test_one(f)
return 'hooray!'


produces

sage: test_lots()
[...]
u(J8)
u(H5, M5)
u(g7, H1, B5)
u(f5, I2, i0, A10)
u(c4, B0, i5, g4, T0)
u(e6, R9, B0, T9, i6, n8)
u(T0, V5, c10, T5, X7, B9, Y4)
u(F8, d9, j6, k10, U0, r6, I10, p3)
u(V5, Q10, z6, n10, V6, f3, J7, o4, F0)
'hooray!'

more

The .operands() method is indeed what I am looking for. Thanks

How about converting f into a string, then stripping off the pieces you don't need? For instance,

s = str(f).split("(")[-1][:-1].split(",")

yields the list s = ['z', ' t']. Or if you want a list of symbolic variables, map(SR, s) = [z, t]. Ugly, but it might do what you need.

more

I prefer the .operand() method as it is less 'ugly'. Thanks for the answer though; I now know about the map(SR, s) approach.

Sure -- I like .operands() better too, now that I know about it!

:-) Never underestimate quick-and-dirty solutions like this.. sometimes you're on the clock and need it to work Right Now(tm) and don't have time to wrestle with the documentation. Plus, if they're general like this one is, it can be used as a test.