[sage-devel] Re: flatten list command

2007-06-28 Thread Nick Alexander

 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

2007-06-28 Thread Hamptonio

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

2007-06-28 Thread boothby

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

2007-06-28 Thread Hamptonio

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

2007-06-28 Thread William Stein
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

2007-06-28 Thread Nick Alexander

 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

2007-06-28 Thread Hamptonio

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

2007-06-28 Thread William Stein

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]
  +