# Stringification of concatenate expressions

I am not sure for the title of this question

This code

nl=3
nc=2
ring=QQ
A=matrix(ring,nl,nc,[3,2,1,4,1,1])
b=vector(ring,[3,5,6])
# b=random_vector(ring,nc)
c=vector(ring,[4,7])
sign=list([">=",">=","<="])
vsign=list([">=",">="])
Zer =[0 for v in vsign]
x = var("x_", n=nc)
L=list(zip(zip(x,vsign),Zer))
LL=[flatten(v) for v in L]
LL


produce this [[x_0, '>=', 0], [x_1, '>=', 0]]. I would like to obtain [['x_0 >= 0'], ['x_1 >= 0']]. If I transform early all the x_i in string I can obtain easily [['x-0 >= 0'], ['x-1 >= 0']]. I wonder why 'stringify' transform - to _.

edit retag close merge delete

What is stringify? The built-in function str doesn't convert _ to -.

Sort by » oldest newest most voted Given your value for LL, namely LL = [[x_0, '>=', 0], [x_1, '>=', 0]], you can do this

sage: [[str(a) for a in b] for b in LL]
[['x_0', '>=', '0'], ['x_1', '>=', '0']]


to convert each entry to a string. You can concatenate those strings using the join method for strings:

sage: [' '.join([str(a) for a in b]) for b in LL]
['x_0 >= 0', 'x_1 >= 0']


To get exactly what you asked for, put the results of that join operation in a list:

sage: [[' '.join([str(a) for a in b])] for b in LL]
[['x_0 >= 0'], ['x_1 >= 0']]

more

if I add the following code to your suggestion LL=[[' '.join([str(a) for a in b])] for b in LL] SR(LL) Sagemath says that the implied expression is badly formed

SR means "symbolic ring", and SR(blah) tries to convert the argument to an element of this ring. x_0 >= 0 will not be an element of any ring. Does eval(LL) do what you want?

Guessing what you aim at ; it's way easier to build expressions rather than concatenating strings :

# Unused for now...
# nl = 3
# nc = 2
ring = QQ
# A = matrix(ring,nl,nc,[3,2,1,4,1,1])
# b = vector(ring,[3,5,6])
c = vector(ring,[4,7])
X = var("x_", n=2)
Zer = *len(X)
# Those operators are builtins but not imported in the toplevel namespace
from _operator import le, ge
vsign = [ge]*2
LL = list(map(lambda u,v:u(*v), vsign, zip(X,Zer)))


will allow for :

sage: LL
[x_0 >= 0, x_1 >= 0]


or, if you really need strings :

sage: list(map(str, LL))
['x_0 >= 0', 'x_1 >= 0']


HTH,

more

Emmanuel I do not understand the syntax map(lambda u,v:u(*v), vsign, zip(X,Zer)). To be clear what troubles me is not map nor the use of a lambda function. a zip() associate element by element the two objects ziped but why u(v) insert the sign inside the two element zipped -- I understand what does *v --. Why I do not understand is why u(v) dispatch the two element zipped arround the vsign.

@Cyrille, here, u is the operator (function), and v is the tuple (expression, value). Therefore u(*v) means "apply the operator(function) u to the arguments denoted by v.

For example, in the first line, the operator u is the ge function, that Sage usually prints <=, and v is the tuple (x_0, 0) ; u(*v) is therefore ge(x, 0), which Sage prints x_0 <= 0.

There is no bloody sign,just a function (operator) and its arguments (operands). The only unusual things are :

• the fact that <= syntax denotes an arithmetic operator, and

• the fact that <= is not acceptable as a Python identifier.

Is that clearer ?

If not, try to read a short tutorial on functional languages ; Lisp (1957) being the forefather of them all, a good Lisp tutorial might be my prescription...