[sage-devel] Re: flatten list command
def flatten(in_list, ltypes=(list, tuple)): ... ltypes -- optional list of particular types to flatten Could you elaborate on the decisions made around iterators here? I can see that flatten([GF(5)]) could be tricky -- is it [GF(5)] or [0, 1, 2, 3, 4]? Nick --~--~-~--~~~---~--~~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://sage.scipy.org/sage/ and http://modular.math.washington.edu/sage/ -~--~~~~--~~--~--~---
[sage-devel] Re: flatten list command
To be honest I didn't give it much thought. This is modified from the simplest code I could find that did the job. flatten(GF(5)) does return [0,1,2,3,4], while flatten([GF(5)]) returns [Finite Field of size 5]. However, you can do: flatten([GF(5)],ltypes = (list, tuple, sage.rings.finite_field.FiniteField_prime_modn)) which returns [0,1,2,3,4]. Since I did a fair amount of python programming before using sage, I guess I tend to favor code that is purely pythonic, which might be against the grain of most sage development. -Marshall On Jun 28, 10:23 am, Nick Alexander [EMAIL PROTECTED] wrote: def flatten(in_list, ltypes=(list, tuple)): ... ltypes -- optional list of particular types to flatten Could you elaborate on the decisions made around iterators here? I can see that flatten([GF(5)]) could be tricky -- is it [GF(5)] or [0, 1, 2, 3, 4]? Nick --~--~-~--~~~---~--~~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://sage.scipy.org/sage/ and http://modular.math.washington.edu/sage/ -~--~~~~--~~--~--~---
[sage-devel] Re: flatten list command
There's a good discussion on the python mailing list regarding flatten: http://mail.python.org/pipermail/python-list/2005-July/330367.html particularly, it's got a number of different implementations, and benchmarks. On Thu, 28 Jun 2007, Hamptonio wrote: I often want to flatten nested lists, and such a command (like Mathematica's Flatten) does not seem to be present in sage. I propose adding such a command into the misc.py. I am appending some candidate code below, and I will also put it on sage-trac (http:// www.sagemath.org:9002/sage_trac/ticket/395) Here's my function: def flatten(in_list, ltypes=(list, tuple)): Flattens a nested list. INPUT: in_list -- a list or tuple ltypes -- optional list of particular types to flatten OUTPUT: a flat list of the entries of in_list EXAMPLES: sage: flatten([[1,1],[1],2]) [1, 1, 1, 2] sage: flatten((['Hi',2,vector(QQ,[1,2,3])],(4,5,6))) ['Hi', 2, (1, 2, 3), 4, 5, 6] sage: flatten((['Hi',2,vector(QQ,[1,2,3])], (4,5,6)),ltypes=(list, tuple, sage.modules.vector_rational_dense.Vector_rational_dense)) ['Hi', 2, 1, 2, 3, 4, 5, 6] index = 0 new_list = [x for x in in_list] while index len(new_list): if not new_list[index]: new_list.pop(index) continue while isinstance(new_list[index], ltypes): new_list[index : index + 1] = list(new_list[index]) index += 1 return new_list --~--~-~--~~~---~--~~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://sage.scipy.org/sage/ and http://modular.math.washington.edu/sage/ -~--~~~~--~~--~--~---
[sage-devel] Re: flatten list command
Interesting. I think I originally ripped mine off from one of the comments at: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/363051 although I've tried to make mine more readable. The thread you linked to has the apparent winner of Ron Adams: def flatten(seq): s = [] while seq: while isinstance(seq[0],list): seq = seq[0]+seq[1:] s.append(seq.pop(0)) return s But that modifies the input, which I consider to be very undesirable. The version I'm using does avoid recursive function calls. Its not clear to me at the moment how to speed it up significantly while avoiding the input modification. -Marshall On Jun 28, 3:15 pm, [EMAIL PROTECTED] wrote: There's a good discussion on the python mailing list regarding flatten: http://mail.python.org/pipermail/python-list/2005-July/330367.html particularly, it's got a number of different implementations, and benchmarks. On Thu, 28 Jun 2007, Hamptonio wrote: I often want to flatten nested lists, and such a command (like Mathematica's Flatten) does not seem to be present in sage. I propose adding such a command into the misc.py. I am appending some candidate code below, and I will also put it on sage-trac (http:// www.sagemath.org:9002/sage_trac/ticket/395) Here's my function: def flatten(in_list, ltypes=(list, tuple)): Flattens a nested list. INPUT: in_list -- a list or tuple ltypes -- optional list of particular types to flatten OUTPUT: a flat list of the entries of in_list EXAMPLES: sage: flatten([[1,1],[1],2]) [1, 1, 1, 2] sage: flatten((['Hi',2,vector(QQ,[1,2,3])],(4,5,6))) ['Hi', 2, (1, 2, 3), 4, 5, 6] sage: flatten((['Hi',2,vector(QQ,[1,2,3])], (4,5,6)),ltypes=(list, tuple, sage.modules.vector_rational_dense.Vector_rational_dense)) ['Hi', 2, 1, 2, 3, 4, 5, 6] index = 0 new_list = [x for x in in_list] while index len(new_list): if not new_list[index]: new_list.pop(index) continue while isinstance(new_list[index], ltypes): new_list[index : index + 1] = list(new_list[index]) index += 1 return new_list --~--~-~--~~~---~--~~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://sage.scipy.org/sage/ and http://modular.math.washington.edu/sage/ -~--~~~~--~~--~--~---
[sage-devel] Re: flatten list command
On 6/28/07, Hamptonio [EMAIL PROTECTED] wrote: Interesting. I think I originally ripped mine off from one of [...] Hi, I've incorporated this into SAGE as a patch. The main things I did were add more examples and delete part of the function which I consider stupid. E.g., you wrote flatten(GF(5)) does return [0,1,2,3,4] but in fact it doesn't -- it returns [1,2,3,4] -- since it removes all things that evaluate to False because of this code: if not new_list[index]: new_list.pop(index) continue So I deleted that code, since I see no reason for it, and all the examples work fine without it. Comments? William [EMAIL PROTECTED]:~/d/sage/sage/misc$ hg export 5194 # HG changeset patch # User William Stein [EMAIL PROTECTED] # Date 1183076918 25200 # Node ID 25f23d18288895f46a6aaa2bd8ef147cde5e31f3 # Parent 65b460226d8173061face0c810fa6cffaf20dc08 Marshall Hampton's flatten command (suitably modified) diff -r 65b460226d81 -r 25f23d182888 sage/misc/all.py --- a/sage/misc/all.py Thu Jun 28 16:17:05 2007 -0700 +++ b/sage/misc/all.py Thu Jun 28 17:28:38 2007 -0700 @@ -6,6 +6,8 @@ from misc import (alarm, srange, xsrange repr_lincomb, tmp_dir, tmp_filename, DOT_SAGE, SAGE_ROOT, SAGE_URL, SAGE_DB, SAGE_TMP, is_32_bit, is_64_bit, newton_method_sizes) + +from flatten import flatten from remote_file import get_remote_file diff -r 65b460226d81 -r 25f23d182888 sage/misc/flatten.py --- /dev/null Thu Jan 01 00:00:00 1970 + +++ b/sage/misc/flatten.py Thu Jun 28 17:28:38 2007 -0700 @@ -0,0 +1,42 @@ +def flatten(in_list, ltypes=(list, tuple)): + + Flattens a nested list. + + INPUT: + in_list -- a list or tuple + ltypes -- optional list of particular types to flatten + + OUTPUT: + a flat list of the entries of in_list + + EXAMPLES: + sage: flatten([[1,1],[1],2]) + [1, 1, 1, 2] + sage: flatten([[1,2,3], (4,5), [[[1],[2) + [1, 2, 3, 4, 5, 1, 2] + + In the following example, the vector isn't flattened because + it is not given in the ltypes input. + sage: flatten((['Hi',2,vector(QQ,[1,2,3])],(4,5,6))) + ['Hi', 2, (1, 2, 3), 4, 5, 6] + + We give the vector type and then even the vector gets flattened: + sage: flatten((['Hi',2,vector(QQ,[1,2,3])], (4,5,6)), ltypes=(list, tuple,sage.modules.vector_rational_dense.Vector_rational_dense)) + ['Hi', 2, 1, 2, 3, 4, 5, 6] + + We flatten a finite field. + sage: flatten(GF(5)) + [0, 1, 2, 3, 4] + sage: flatten([GF(5)]) + [Finite Field of size 5] + sage: flatten([GF(5)], ltypes = (list, tuple, sage.rings.finite_field.FiniteField_prime_modn)) + [0, 1, 2, 3, 4] + + + index = 0 + new_list = [x for x in in_list] + while index len(new_list): + while isinstance(new_list[index], ltypes): + new_list[index : index + 1] = list(new_list[index]) + index += 1 + return new_list William --~--~-~--~~~---~--~~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://sage.scipy.org/sage/ and http://modular.math.washington.edu/sage/ -~--~~~~--~~--~--~---
[sage-devel] Re: flatten list command
I've incorporated this into SAGE as a patch. I like the final form. [EMAIL PROTECTED]:~/d/sage/sage/misc$ hg export 5194 # HG changeset patch # User William Stein [EMAIL PROTECTED] # Date 1183076918 25200 # Node ID 25f23d18288895f46a6aaa2bd8ef147cde5e31f3 # Parent 65b460226d8173061face0c810fa6cffaf20dc08 Marshall Hampton's flatten command (suitably modified) diff -r 65b460226d81 -r 25f23d182888 sage/misc/all.py --- a/sage/misc/all.py Thu Jun 28 16:17:05 2007 -0700 +++ b/sage/misc/all.py Thu Jun 28 17:28:38 2007 -0700 @@ -6,6 +6,8 @@ from misc import (alarm, srange, xsrange repr_lincomb, tmp_dir, tmp_filename, DOT_SAGE, SAGE_ROOT, SAGE_URL, SAGE_DB, SAGE_TMP, is_32_bit, is_64_bit, newton_method_sizes) + +from flatten import flatten Did this really need its own file? Nick --~--~-~--~~~---~--~~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://sage.scipy.org/sage/ and http://modular.math.washington.edu/sage/ -~--~~~~--~~--~--~---
[sage-devel] Re: flatten list command
Whoops! - sorry about the misreporting on the GF(5) behavior. I was playing around with lots of similar versions and I must have gotten confused. That extra loop you deleted was put in to avoid errors on weird cases like: flatten([[]]), which gives an IndexError: list index out of range if the extra loop is removed. But it was badly done. Here is another attempt which I think behaves OK on nested empty lists and things that evaluate to False: def flatten(in_list, ltypes=(list, tuple)): Flattens a nested list. INPUT: in_list -- a list or tuple ltypes -- optional list of particular types to flatten OUTPUT: a flat list of the entries of in_list EXAMPLES: sage: flatten([[1,1],[1],2]) [1, 1, 1, 2] sage: flatten([[1,2,3], (4,5), [[[1],[2) [1, 2, 3, 4, 5, 1, 2] In the following example, the vector isn't flattened because it is not given in the ltypes input. sage: flatten((['Hi',2,vector(QQ,[1,2,3])],(4,5,6))) ['Hi', 2, (1, 2, 3), 4, 5, 6] We give the vector type and then even the vector gets flattened: sage: flatten((['Hi',2,vector(QQ,[1,2,3])], (4,5,6)), ltypes=(list, tuple,sage.modules.vector_rational_dense.Vector_rational_dense)) ['Hi', 2, 1, 2, 3, 4, 5, 6] We flatten a finite field. sage: flatten(GF(5)) [0, 1, 2, 3, 4] sage: flatten([GF(5)]) [Finite Field of size 5] sage: flatten([GF(5)], ltypes = (list, tuple, sage.rings.finite_field.FiniteField_prime_modn)) [0, 1, 2, 3, 4] index = 0 new_list = [x for x in in_list] while index len(new_list): while isinstance(new_list[index], ltypes): if len(new_list[index]) != 0: new_list[index : index + 1] = list(new_list[index]) else: new_list.pop(index) break index += 1 return new_list On Jun 28, 7:40 pm, William Stein [EMAIL PROTECTED] wrote: On 6/28/07, Hamptonio [EMAIL PROTECTED] wrote: Interesting. I think I originally ripped mine off from one of [...] Hi, I've incorporated this into SAGE as a patch. The main things I did were add more examples and delete part of the function which I consider stupid. E.g., you wrote flatten(GF(5)) does return [0,1,2,3,4] but in fact it doesn't -- it returns [1,2,3,4] -- since it removes all things that evaluate to False because of this code: if not new_list[index]: new_list.pop(index) continue So I deleted that code, since I see no reason for it, and all the examples work fine without it. Comments? William [EMAIL PROTECTED]:~/d/sage/sage/misc$ hg export 5194 # HG changeset patch # User William Stein [EMAIL PROTECTED] # Date 1183076918 25200 # Node ID 25f23d18288895f46a6aaa2bd8ef147cde5e31f3 # Parent 65b460226d8173061face0c810fa6cffaf20dc08 Marshall Hampton's flatten command (suitably modified) diff -r 65b460226d81 -r 25f23d182888 sage/misc/all.py --- a/sage/misc/all.py Thu Jun 28 16:17:05 2007 -0700 +++ b/sage/misc/all.py Thu Jun 28 17:28:38 2007 -0700 @@ -6,6 +6,8 @@ from misc import (alarm, srange, xsrange repr_lincomb, tmp_dir, tmp_filename, DOT_SAGE, SAGE_ROOT, SAGE_URL, SAGE_DB, SAGE_TMP, is_32_bit, is_64_bit, newton_method_sizes) + +from flatten import flatten from remote_file import get_remote_file diff -r 65b460226d81 -r 25f23d182888 sage/misc/flatten.py --- /dev/null Thu Jan 01 00:00:00 1970 + +++ b/sage/misc/flatten.py Thu Jun 28 17:28:38 2007 -0700 @@ -0,0 +1,42 @@ +def flatten(in_list, ltypes=(list, tuple)): + + Flattens a nested list. + + INPUT: + in_list -- a list or tuple + ltypes -- optional list of particular types to flatten + + OUTPUT: + a flat list of the entries of in_list + + EXAMPLES: + sage: flatten([[1,1],[1],2]) + [1, 1, 1, 2] + sage: flatten([[1,2,3], (4,5), [[[1],[2) + [1, 2, 3, 4, 5, 1, 2] + + In the following example, the vector isn't flattened because + it is not given in the ltypes input. + sage: flatten((['Hi',2,vector(QQ,[1,2,3])],(4,5,6))) + ['Hi', 2, (1, 2, 3), 4, 5, 6] + + We give the vector type and then even the vector gets flattened: + sage: flatten((['Hi',2,vector(QQ,[1,2,3])], (4,5,6)), ltypes=(list, tuple,sage.modules.vector_rational_dense.Vector_rational_dense)) + ['Hi', 2, 1, 2, 3, 4, 5, 6] + + We flatten a finite field. + sage: flatten(GF(5)) + [0, 1, 2, 3, 4] + sage: flatten([GF(5)]) + [Finite Field of size 5] + sage: flatten([GF(5)], ltypes = (list, tuple, sage.rings.finite_field.FiniteField_prime_modn)) + [0, 1, 2, 3, 4] + + + index = 0 + new_list = [x for x in in_list] + while index len(new_list): + while isinstance(new_list[index], ltypes): +
[sage-devel] Re: flatten list command
On 6/28/07, Hamptonio [EMAIL PROTECTED] wrote: Whoops! - sorry about the misreporting on the GF(5) behavior. I was playing around with lots of similar versions and I must have gotten confused. That extra loop you deleted was put in to avoid errors on weird cases like: flatten([[]]), which gives an IndexError: list index out of Thanks. I've amended the patch with this improvement, and included some docstrings. -- William range if the extra loop is removed. But it was badly done. Here is another attempt which I think behaves OK on nested empty lists and things that evaluate to False: def flatten(in_list, ltypes=(list, tuple)): Flattens a nested list. INPUT: in_list -- a list or tuple ltypes -- optional list of particular types to flatten OUTPUT: a flat list of the entries of in_list EXAMPLES: sage: flatten([[1,1],[1],2]) [1, 1, 1, 2] sage: flatten([[1,2,3], (4,5), [[[1],[2) [1, 2, 3, 4, 5, 1, 2] In the following example, the vector isn't flattened because it is not given in the ltypes input. sage: flatten((['Hi',2,vector(QQ,[1,2,3])],(4,5,6))) ['Hi', 2, (1, 2, 3), 4, 5, 6] We give the vector type and then even the vector gets flattened: sage: flatten((['Hi',2,vector(QQ,[1,2,3])], (4,5,6)), ltypes=(list, tuple,sage.modules.vector_rational_dense.Vector_rational_dense)) ['Hi', 2, 1, 2, 3, 4, 5, 6] We flatten a finite field. sage: flatten(GF(5)) [0, 1, 2, 3, 4] sage: flatten([GF(5)]) [Finite Field of size 5] sage: flatten([GF(5)], ltypes = (list, tuple, sage.rings.finite_field.FiniteField_prime_modn)) [0, 1, 2, 3, 4] index = 0 new_list = [x for x in in_list] while index len(new_list): while isinstance(new_list[index], ltypes): if len(new_list[index]) != 0: new_list[index : index + 1] = list(new_list[index]) else: new_list.pop(index) break index += 1 return new_list On Jun 28, 7:40 pm, William Stein [EMAIL PROTECTED] wrote: On 6/28/07, Hamptonio [EMAIL PROTECTED] wrote: Interesting. I think I originally ripped mine off from one of [...] Hi, I've incorporated this into SAGE as a patch. The main things I did were add more examples and delete part of the function which I consider stupid. E.g., you wrote flatten(GF(5)) does return [0,1,2,3,4] but in fact it doesn't -- it returns [1,2,3,4] -- since it removes all things that evaluate to False because of this code: if not new_list[index]: new_list.pop(index) continue So I deleted that code, since I see no reason for it, and all the examples work fine without it. Comments? William [EMAIL PROTECTED]:~/d/sage/sage/misc$ hg export 5194 # HG changeset patch # User William Stein [EMAIL PROTECTED] # Date 1183076918 25200 # Node ID 25f23d18288895f46a6aaa2bd8ef147cde5e31f3 # Parent 65b460226d8173061face0c810fa6cffaf20dc08 Marshall Hampton's flatten command (suitably modified) diff -r 65b460226d81 -r 25f23d182888 sage/misc/all.py --- a/sage/misc/all.py Thu Jun 28 16:17:05 2007 -0700 +++ b/sage/misc/all.py Thu Jun 28 17:28:38 2007 -0700 @@ -6,6 +6,8 @@ from misc import (alarm, srange, xsrange repr_lincomb, tmp_dir, tmp_filename, DOT_SAGE, SAGE_ROOT, SAGE_URL, SAGE_DB, SAGE_TMP, is_32_bit, is_64_bit, newton_method_sizes) + +from flatten import flatten from remote_file import get_remote_file diff -r 65b460226d81 -r 25f23d182888 sage/misc/flatten.py --- /dev/null Thu Jan 01 00:00:00 1970 + +++ b/sage/misc/flatten.py Thu Jun 28 17:28:38 2007 -0700 @@ -0,0 +1,42 @@ +def flatten(in_list, ltypes=(list, tuple)): + + Flattens a nested list. + + INPUT: + in_list -- a list or tuple + ltypes -- optional list of particular types to flatten + + OUTPUT: + a flat list of the entries of in_list + + EXAMPLES: + sage: flatten([[1,1],[1],2]) + [1, 1, 1, 2] + sage: flatten([[1,2,3], (4,5), [[[1],[2) + [1, 2, 3, 4, 5, 1, 2] + + In the following example, the vector isn't flattened because + it is not given in the ltypes input. + sage: flatten((['Hi',2,vector(QQ,[1,2,3])],(4,5,6))) + ['Hi', 2, (1, 2, 3), 4, 5, 6] + + We give the vector type and then even the vector gets flattened: + sage: flatten((['Hi',2,vector(QQ,[1,2,3])], (4,5,6)), ltypes=(list, tuple,sage.modules.vector_rational_dense.Vector_rational_dense)) + ['Hi', 2, 1, 2, 3, 4, 5, 6] + + We flatten a finite field. + sage: flatten(GF(5)) + [0, 1, 2, 3, 4] + sage: flatten([GF(5)]) + [Finite Field of size 5] +