ASKSAGE: Sage Q&A Forum - RSS feedhttps://ask.sagemath.org/questions/Q&A Forum for SageenCopyright Sage, 2010. Some rights reserved under creative commons license.Fri, 27 Nov 2020 04:40:37 +0100Erasing some of the decimals in a listhttps://ask.sagemath.org/question/54401/erasing-some-of-the-decimals-in-a-list/ This is a nice table to the reserve of the to long decimals
A=[[10,10,10,10,10,10,10,10,10,10],[100,0,0,0,0,0,0,0,0,0],[11.1,11.1,11.1,11.1,11.1,11.1,11.1,11.1,11.1,0]
,[20,20,20,20,20,0,0,0,0,0],[50,25,12.5,6.25,3.125,1.56,0.78,0.39,0.19,0.09]]
t=table(A,header_row=["$1$","$2$","$3$","$4$","$5$","$6$","$7$","$8$","$9$","$10$"],header_column=["","Équi-Rep","Tout pour un","Un déshérité","Injuste pour 1/2","$5$","Injuste croissante"])
show(t)
I have tried to construct a function `f(x)=round(x,2)` and then to use `A.map_apply(f)` but this doesnot works since
`f(x)=round(x,2)` generates an error. How shouild I do ?Thu, 26 Nov 2020 19:11:43 +0100https://ask.sagemath.org/question/54401/erasing-some-of-the-decimals-in-a-list/Answer by slelievre for <p>This is a nice table to the reserve of the to long decimals</p>
<pre><code>A=[[10,10,10,10,10,10,10,10,10,10],[100,0,0,0,0,0,0,0,0,0],[11.1,11.1,11.1,11.1,11.1,11.1,11.1,11.1,11.1,0]
,[20,20,20,20,20,0,0,0,0,0],[50,25,12.5,6.25,3.125,1.56,0.78,0.39,0.19,0.09]]
t=table(A,header_row=["$1$","$2$","$3$","$4$","$5$","$6$","$7$","$8$","$9$","$10$"],header_column=["","Équi-Rep","Tout pour un","Un déshérité","Injuste pour 1/2","$5$","Injuste croissante"])
show(t)
</code></pre>
<p>I have tried to construct a function <code>f(x)=round(x,2)</code> and then to use <code>A.map_apply(f)</code> but this doesnot works since
<code>f(x)=round(x,2)</code> generates an error. How shouild I do ?</p>
https://ask.sagemath.org/question/54401/erasing-some-of-the-decimals-in-a-list/?answer=54402#post-id-54402Here is a solution taking advantage of the following:
- elements of `RDF` are represented with no trailing decimal zeros
- matrices over `RDF` have a `round` method that can round to n decimal digits
There might be simpler ways, but hopefully this helps.
Define `A` as a list of lists:
sage: A = [[10] * 10, [100] + [0] * 9, [100/9] * 9 + [0]]
sage: A.extend([[20] * 5 + [0] * 5, [50/2**n for n in range(10)]])
Make a deep copy, so we can change it without changing `A`:
sage: D = deepcopy(A)
Round the rows with non-integer values:
sage: D[2] = list(matrix(RDF, A[2]).round(1)[0])
sage: D[4] = list(matrix(RDF, A[4]).round(2)[0])
Set table headers:
sage: hr = [f"${n}$" for n in (1 .. 10)]
sage: hc = ["", "Équirép", "Tout pour un", "Un déshérité"]
sage: hc += ["Injus moitié", "Injus croiss"]
Build the table:
sage: t = table(D, header_row=hr, header_column=hc)
The table in text mode:
sage: t
| $1$ $2$ $3$ $4$ $5$ $6$ $7$ $8$ $9$ $10$
+--------------+------+------+------+------+------+------+------+------+------+------+
Équirép | 10 10 10 10 10 10 10 10 10 10
Tout pour un | 100 0 0 0 0 0 0 0 0 0
Un déshérité | 11.1 11.1 11.1 11.1 11.1 11.1 11.1 11.1 11.1 0.0
Injus moitié | 20 20 20 20 20 0 0 0 0 0
Injus croiss | 50.0 25.0 12.5 6.25 3.12 1.56 0.78 0.39 0.2 0.1
The latexed table:
sage: view(t)
![Tableau de comparaison, version a](/upfiles/1606433836303425.png)
Simpler solution, inspired by the answer given by @dsejas.
Here `A`, `hr`, `hc` are as above.
Round only non-integer entries; adapt rounding precision to get 3 significant digits:
sage: f = lambda a: a if a in ZZ else round(a, 2 - floor(log(a, 10)))
sage: D = [[f(a) for a in r] for r in A]
Build the table:
sage: t = table(D, header_row=hr, header_column=hc)
The table in text mode:
sage: t
| $1$ $2$ $3$ $4$ $5$ $6$ $7$ $8$ $9$ $10$
+--------------+------+------+------+------+------+------+-------+-------+-------+--------+
Équirép | 10 10 10 10 10 10 10 10 10 10
Tout pour un | 100 0 0 0 0 0 0 0 0 0
Un déshérité | 11.1 11.1 11.1 11.1 11.1 11.1 11.1 11.1 11.1 0
Injus moitié | 20 20 20 20 20 0 0 0 0 0
Injus croiss | 50 25 12.5 6.25 3.12 1.56 0.781 0.391 0.195 0.0977
The latexed table:
sage: view(t)
![Tableau de comparaison, version b](/upfiles/1606431094219207.png)Thu, 26 Nov 2020 19:39:06 +0100https://ask.sagemath.org/question/54401/erasing-some-of-the-decimals-in-a-list/?answer=54402#post-id-54402Answer by dsejas for <p>This is a nice table to the reserve of the to long decimals</p>
<pre><code>A=[[10,10,10,10,10,10,10,10,10,10],[100,0,0,0,0,0,0,0,0,0],[11.1,11.1,11.1,11.1,11.1,11.1,11.1,11.1,11.1,0]
,[20,20,20,20,20,0,0,0,0,0],[50,25,12.5,6.25,3.125,1.56,0.78,0.39,0.19,0.09]]
t=table(A,header_row=["$1$","$2$","$3$","$4$","$5$","$6$","$7$","$8$","$9$","$10$"],header_column=["","Équi-Rep","Tout pour un","Un déshérité","Injuste pour 1/2","$5$","Injuste croissante"])
show(t)
</code></pre>
<p>I have tried to construct a function <code>f(x)=round(x,2)</code> and then to use <code>A.map_apply(f)</code> but this doesnot works since
<code>f(x)=round(x,2)</code> generates an error. How shouild I do ?</p>
https://ask.sagemath.org/question/54401/erasing-some-of-the-decimals-in-a-list/?answer=54405#post-id-54405Hello, @Cyrille! I believe that @slelievre has already given you a perfect solution for your problem, so i am just going to complement it with a few comments and alternatives for you, or any reader looking for the way to work with maps. However, I highly recommend using @slelievre's answer, which is way more efficient and elegant.
You cannot define `f(x) = round(x, 2)`, because this is a symbolic definition, but `round()` is not a symbolic function. See the answer to [this question](https://ask.sagemath.org/question/47672/is-this-a-bug-or-intended-behavior/) for more details (I also made a similar mistake.) Remember that syntax like `f(x) = x^2` is actually syntactic sugar defined by Sage for comfort. Instead, when you can't use that type of definitions, you should use a Python function definition:
def f(x):
return round(x, 2)
Now, a similar approach to yours would be to use the `map()` function; this acts on the elements of a list. In your particular case, `A` is a list of lists, so you should define a function that takes a list (a row of your table) and returns a list with its elements rounded off (a new row of your table):
def f(row): # row is a row of your table "A" (automatically chosen by "map()")
result = [] # this will be the new rounded off row
for x in row:
result.append(round(x, 2)) # this applies the "round()" function to every element of "row" and appends it to the new row
return result
Now, you can apply this to your table `A` with this code:
A=[[10,10,10,10,10,10,10,10,10,10],[100,0,0,0,0,0,0,0,0,0],
[11.1,11.1,11.1,11.1,11.1,11.1,11.1,11.1,11.1,0],
[20,20,20,20,20,0,0,0,0,0],[50,25,12.5,6.25,3.125,1.56,0.78,0.39,0.19,0.09]]
temp = map(f, A)
Now `temp` is a Python map that will round your table elements. In order to trigger the process and obtain a new table (list of lists), you must write `list(A)`, like in the following code:
t=table(list(temp),header_row="$1$","$2$","$3$","$4$","$5$","$6$","$7$","$8$","$9$","$10$"],
header_column["","ÉquiRep","Tout pour un","Un déshérité","Injuste pour 1/2","$5$",
"Injuste croissante"])
show(t)
Following @slelievre's answer, you can also use the following function:
def f(row):
result = []
for x in row:
result.append(RDF(x))
return result
Once again, this syntax is necessary, since `RDF()` is not a symbolic function.
I hope this helps!Thu, 26 Nov 2020 20:07:30 +0100https://ask.sagemath.org/question/54401/erasing-some-of-the-decimals-in-a-list/?answer=54405#post-id-54405Comment by slelievre for <p>Hello, <a href="/users/26565/cyrille/">@Cyrille</a>! I believe that <a href="/users/1092/slelievre/">@slelievre</a> has already given you a perfect solution for your problem, so i am just going to complement it with a few comments and alternatives for you, or any reader looking for the way to work with maps. However, I highly recommend using <a href="/users/1092/slelievre/">@slelievre</a>'s answer, which is way more efficient and elegant.</p>
<p>You cannot define <code>f(x) = round(x, 2)</code>, because this is a symbolic definition, but <code>round()</code> is not a symbolic function. See the answer to <a href="https://ask.sagemath.org/question/47672/is-this-a-bug-or-intended-behavior/">this question</a> for more details (I also made a similar mistake.) Remember that syntax like <code>f(x) = x^2</code> is actually syntactic sugar defined by Sage for comfort. Instead, when you can't use that type of definitions, you should use a Python function definition:</p>
<pre><code>def f(x):
return round(x, 2)
</code></pre>
<p>Now, a similar approach to yours would be to use the <code>map()</code> function; this acts on the elements of a list. In your particular case, <code>A</code> is a list of lists, so you should define a function that takes a list (a row of your table) and returns a list with its elements rounded off (a new row of your table):</p>
<pre><code>def f(row): # row is a row of your table "A" (automatically chosen by "map()")
result = [] # this will be the new rounded off row
for x in row:
result.append(round(x, 2)) # this applies the "round()" function to every element of "row" and appends it to the new row
return result
</code></pre>
<p>Now, you can apply this to your table <code>A</code> with this code:</p>
<pre><code>A=[[10,10,10,10,10,10,10,10,10,10],[100,0,0,0,0,0,0,0,0,0],
[11.1,11.1,11.1,11.1,11.1,11.1,11.1,11.1,11.1,0],
[20,20,20,20,20,0,0,0,0,0],[50,25,12.5,6.25,3.125,1.56,0.78,0.39,0.19,0.09]]
temp = map(f, A)
</code></pre>
<p>Now <code>temp</code> is a Python map that will round your table elements. In order to trigger the process and obtain a new table (list of lists), you must write <code>list(A)</code>, like in the following code:</p>
<pre><code>t=table(list(temp),header_row="$1$","$2$","$3$","$4$","$5$","$6$","$7$","$8$","$9$","$10$"],
header_column["","ÉquiRep","Tout pour un","Un déshérité","Injuste pour 1/2","$5$",
"Injuste croissante"])
show(t)
</code></pre>
<p>Following <a href="/users/1092/slelievre/">@slelievre</a>'s answer, you can also use the following function:</p>
<pre><code> def f(row):
result = []
for x in row:
result.append(RDF(x))
return result
</code></pre>
<p>Once again, this syntax is necessary, since <code>RDF()</code> is not a symbolic function.</p>
<p>I hope this helps!</p>
https://ask.sagemath.org/question/54401/erasing-some-of-the-decimals-in-a-list/?comment=54406#post-id-54406Note: you probably meant `list(temp)` rather than `list(A)`.Thu, 26 Nov 2020 21:19:28 +0100https://ask.sagemath.org/question/54401/erasing-some-of-the-decimals-in-a-list/?comment=54406#post-id-54406Comment by dsejas for <p>Hello, <a href="/users/26565/cyrille/">@Cyrille</a>! I believe that <a href="/users/1092/slelievre/">@slelievre</a> has already given you a perfect solution for your problem, so i am just going to complement it with a few comments and alternatives for you, or any reader looking for the way to work with maps. However, I highly recommend using <a href="/users/1092/slelievre/">@slelievre</a>'s answer, which is way more efficient and elegant.</p>
<p>You cannot define <code>f(x) = round(x, 2)</code>, because this is a symbolic definition, but <code>round()</code> is not a symbolic function. See the answer to <a href="https://ask.sagemath.org/question/47672/is-this-a-bug-or-intended-behavior/">this question</a> for more details (I also made a similar mistake.) Remember that syntax like <code>f(x) = x^2</code> is actually syntactic sugar defined by Sage for comfort. Instead, when you can't use that type of definitions, you should use a Python function definition:</p>
<pre><code>def f(x):
return round(x, 2)
</code></pre>
<p>Now, a similar approach to yours would be to use the <code>map()</code> function; this acts on the elements of a list. In your particular case, <code>A</code> is a list of lists, so you should define a function that takes a list (a row of your table) and returns a list with its elements rounded off (a new row of your table):</p>
<pre><code>def f(row): # row is a row of your table "A" (automatically chosen by "map()")
result = [] # this will be the new rounded off row
for x in row:
result.append(round(x, 2)) # this applies the "round()" function to every element of "row" and appends it to the new row
return result
</code></pre>
<p>Now, you can apply this to your table <code>A</code> with this code:</p>
<pre><code>A=[[10,10,10,10,10,10,10,10,10,10],[100,0,0,0,0,0,0,0,0,0],
[11.1,11.1,11.1,11.1,11.1,11.1,11.1,11.1,11.1,0],
[20,20,20,20,20,0,0,0,0,0],[50,25,12.5,6.25,3.125,1.56,0.78,0.39,0.19,0.09]]
temp = map(f, A)
</code></pre>
<p>Now <code>temp</code> is a Python map that will round your table elements. In order to trigger the process and obtain a new table (list of lists), you must write <code>list(A)</code>, like in the following code:</p>
<pre><code>t=table(list(temp),header_row="$1$","$2$","$3$","$4$","$5$","$6$","$7$","$8$","$9$","$10$"],
header_column["","ÉquiRep","Tout pour un","Un déshérité","Injuste pour 1/2","$5$",
"Injuste croissante"])
show(t)
</code></pre>
<p>Following <a href="/users/1092/slelievre/">@slelievre</a>'s answer, you can also use the following function:</p>
<pre><code> def f(row):
result = []
for x in row:
result.append(RDF(x))
return result
</code></pre>
<p>Once again, this syntax is necessary, since <code>RDF()</code> is not a symbolic function.</p>
<p>I hope this helps!</p>
https://ask.sagemath.org/question/54401/erasing-some-of-the-decimals-in-a-list/?comment=54408#post-id-54408Opps, yes, I meant `list(temp)`. I am correcting it now.
Also, thank you for the suggested code simplifications.Fri, 27 Nov 2020 01:39:04 +0100https://ask.sagemath.org/question/54401/erasing-some-of-the-decimals-in-a-list/?comment=54408#post-id-54408Comment by slelievre for <p>Hello, <a href="/users/26565/cyrille/">@Cyrille</a>! I believe that <a href="/users/1092/slelievre/">@slelievre</a> has already given you a perfect solution for your problem, so i am just going to complement it with a few comments and alternatives for you, or any reader looking for the way to work with maps. However, I highly recommend using <a href="/users/1092/slelievre/">@slelievre</a>'s answer, which is way more efficient and elegant.</p>
<p>You cannot define <code>f(x) = round(x, 2)</code>, because this is a symbolic definition, but <code>round()</code> is not a symbolic function. See the answer to <a href="https://ask.sagemath.org/question/47672/is-this-a-bug-or-intended-behavior/">this question</a> for more details (I also made a similar mistake.) Remember that syntax like <code>f(x) = x^2</code> is actually syntactic sugar defined by Sage for comfort. Instead, when you can't use that type of definitions, you should use a Python function definition:</p>
<pre><code>def f(x):
return round(x, 2)
</code></pre>
<p>Now, a similar approach to yours would be to use the <code>map()</code> function; this acts on the elements of a list. In your particular case, <code>A</code> is a list of lists, so you should define a function that takes a list (a row of your table) and returns a list with its elements rounded off (a new row of your table):</p>
<pre><code>def f(row): # row is a row of your table "A" (automatically chosen by "map()")
result = [] # this will be the new rounded off row
for x in row:
result.append(round(x, 2)) # this applies the "round()" function to every element of "row" and appends it to the new row
return result
</code></pre>
<p>Now, you can apply this to your table <code>A</code> with this code:</p>
<pre><code>A=[[10,10,10,10,10,10,10,10,10,10],[100,0,0,0,0,0,0,0,0,0],
[11.1,11.1,11.1,11.1,11.1,11.1,11.1,11.1,11.1,0],
[20,20,20,20,20,0,0,0,0,0],[50,25,12.5,6.25,3.125,1.56,0.78,0.39,0.19,0.09]]
temp = map(f, A)
</code></pre>
<p>Now <code>temp</code> is a Python map that will round your table elements. In order to trigger the process and obtain a new table (list of lists), you must write <code>list(A)</code>, like in the following code:</p>
<pre><code>t=table(list(temp),header_row="$1$","$2$","$3$","$4$","$5$","$6$","$7$","$8$","$9$","$10$"],
header_column["","ÉquiRep","Tout pour un","Un déshérité","Injuste pour 1/2","$5$",
"Injuste croissante"])
show(t)
</code></pre>
<p>Following <a href="/users/1092/slelievre/">@slelievre</a>'s answer, you can also use the following function:</p>
<pre><code> def f(row):
result = []
for x in row:
result.append(RDF(x))
return result
</code></pre>
<p>Once again, this syntax is necessary, since <code>RDF()</code> is not a symbolic function.</p>
<p>I hope this helps!</p>
https://ask.sagemath.org/question/54401/erasing-some-of-the-decimals-in-a-list/?comment=54409#post-id-54409No problem. I like using comprehensions instead of
initialising an empty list and appending in a for loop.
I find it more concise, elegant and expressive. It may be faster too.
Same for dictionaries, see [Stack Overflow answer 64949287](https://stackoverflow.com/a/64949287).Fri, 27 Nov 2020 04:40:37 +0100https://ask.sagemath.org/question/54401/erasing-some-of-the-decimals-in-a-list/?comment=54409#post-id-54409Comment by slelievre for <p>Hello, <a href="/users/26565/cyrille/">@Cyrille</a>! I believe that <a href="/users/1092/slelievre/">@slelievre</a> has already given you a perfect solution for your problem, so i am just going to complement it with a few comments and alternatives for you, or any reader looking for the way to work with maps. However, I highly recommend using <a href="/users/1092/slelievre/">@slelievre</a>'s answer, which is way more efficient and elegant.</p>
<p>You cannot define <code>f(x) = round(x, 2)</code>, because this is a symbolic definition, but <code>round()</code> is not a symbolic function. See the answer to <a href="https://ask.sagemath.org/question/47672/is-this-a-bug-or-intended-behavior/">this question</a> for more details (I also made a similar mistake.) Remember that syntax like <code>f(x) = x^2</code> is actually syntactic sugar defined by Sage for comfort. Instead, when you can't use that type of definitions, you should use a Python function definition:</p>
<pre><code>def f(x):
return round(x, 2)
</code></pre>
<p>Now, a similar approach to yours would be to use the <code>map()</code> function; this acts on the elements of a list. In your particular case, <code>A</code> is a list of lists, so you should define a function that takes a list (a row of your table) and returns a list with its elements rounded off (a new row of your table):</p>
<pre><code>def f(row): # row is a row of your table "A" (automatically chosen by "map()")
result = [] # this will be the new rounded off row
for x in row:
result.append(round(x, 2)) # this applies the "round()" function to every element of "row" and appends it to the new row
return result
</code></pre>
<p>Now, you can apply this to your table <code>A</code> with this code:</p>
<pre><code>A=[[10,10,10,10,10,10,10,10,10,10],[100,0,0,0,0,0,0,0,0,0],
[11.1,11.1,11.1,11.1,11.1,11.1,11.1,11.1,11.1,0],
[20,20,20,20,20,0,0,0,0,0],[50,25,12.5,6.25,3.125,1.56,0.78,0.39,0.19,0.09]]
temp = map(f, A)
</code></pre>
<p>Now <code>temp</code> is a Python map that will round your table elements. In order to trigger the process and obtain a new table (list of lists), you must write <code>list(A)</code>, like in the following code:</p>
<pre><code>t=table(list(temp),header_row="$1$","$2$","$3$","$4$","$5$","$6$","$7$","$8$","$9$","$10$"],
header_column["","ÉquiRep","Tout pour un","Un déshérité","Injuste pour 1/2","$5$",
"Injuste croissante"])
show(t)
</code></pre>
<p>Following <a href="/users/1092/slelievre/">@slelievre</a>'s answer, you can also use the following function:</p>
<pre><code> def f(row):
result = []
for x in row:
result.append(RDF(x))
return result
</code></pre>
<p>Once again, this syntax is necessary, since <code>RDF()</code> is not a symbolic function.</p>
<p>I hope this helps!</p>
https://ask.sagemath.org/question/54401/erasing-some-of-the-decimals-in-a-list/?comment=54407#post-id-54407Note: with `A` as in the question, a maybe simpler way to use `round` would be:
sage: f = lambda x: round(x, 2)
sage: D = [[f(x) for x in row] for row in A]
or if one likes using `map`:
sage: f = lambda x: round(x, 2)
sage: ff = lambda row: list(map(f, row))
sage: D = list(map(ff, A))
and then
sage: t = table(D, ...)Thu, 26 Nov 2020 21:24:22 +0100https://ask.sagemath.org/question/54401/erasing-some-of-the-decimals-in-a-list/?comment=54407#post-id-54407