Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

flatten command for nested lists #395

Closed
sagetrac-mhampton mannequin opened this issue Jun 28, 2007 · 7 comments
Closed

flatten command for nested lists #395

sagetrac-mhampton mannequin opened this issue Jun 28, 2007 · 7 comments

Comments

@sagetrac-mhampton
Copy link
Mannequin

sagetrac-mhampton mannequin commented Jun 28, 2007

The attached file has a candidate function for a flatten command. The default types to flatten are lists and tuples, but more can be added.

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

Component: basic arithmetic

Keywords: lists, flatten

Issue created by migration from https://trac.sagemath.org/ticket/395

@sagetrac-mhampton sagetrac-mhampton mannequin self-assigned this Jun 28, 2007
@sagetrac-mhampton
Copy link
Mannequin Author

sagetrac-mhampton mannequin commented Jul 5, 2007

comment:2

New version:

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

@sagetrac-mabshoff
Copy link
Mannequin

sagetrac-mabshoff mannequin commented Aug 23, 2007

comment:3

Sage 2.8.2 has a flatten command. It also seems to work on nested lists:

sage: L
[[1, 2], [1, 2]]
sage: flatten(L)
[1, 2, 1, 2]
sage: L=[L,[L,[L,[L]]]]
sage: L
[[[1, 2], [1, 2]], [[[1, 2], [1, 2]], [[[1, 2], [1, 2]], [[[1, 2], [1, 2]]]]]]
sage: flatten(L)
[1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2]

So am I correct to assume that this ticket can be closed?

Cheers,

Michael

@sagetrac-mabshoff sagetrac-mabshoff mannequin added this to the sage-2.8.3 milestone Aug 23, 2007
@williamstein
Copy link
Contributor

comment:4

Yep, this has been in SAGE a while.

@sagetrac-mhampton
Copy link
Mannequin Author

sagetrac-mhampton mannequin commented Sep 11, 2007

comment:5

This still has some problems on empty lists, which I (Marshall Hampton) will try to fix soon. the simplest example of the problem for the current (2.8.4.1) behavior is:
flatten([[],[]])
[[]]

It should return [].

@sagetrac-mhampton sagetrac-mhampton mannequin added t: bug and removed t: enhancement labels Sep 11, 2007
@sagetrac-mhampton sagetrac-mhampton mannequin removed this from the sage-2.8.3 milestone Sep 11, 2007
@sagetrac-mhampton sagetrac-mhampton mannequin added the t: feature label Sep 11, 2007
@sagetrac-mhampton sagetrac-mhampton mannequin reopened this Sep 11, 2007
@sagetrac-mhampton
Copy link
Mannequin Author

sagetrac-mhampton mannequin commented Sep 11, 2007

comment:7

Replying to @sagetrac-mhampton:

Sorry, I am not used to this formatting. My example should be:

flatten([[],[]])

[[]]

@sagetrac-mhampton
Copy link
Mannequin Author

sagetrac-mhampton mannequin commented Sep 11, 2007

comment:9

Here is a new version that I believe fixes the problem.

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]

   Degenerate cases:
      sage: flatten([[],[]])
      []
      sage: flatten([[[]]])
      []
   """
   index = 0
   new_list = [x for x in in_list]
   while index < len(new_list):
      while isinstance(new_list[index], ltypes):
         v = list(new_list[index])
         if len(v) != 0:
            new_list[index : index + 1] = v
         else:
            new_list.pop(index)
            index += -1
            break
      index += 1
   return new_list

@sagetrac-mhampton sagetrac-mhampton mannequin added this to the sage-2.9.1 milestone Sep 11, 2007
@williamstein williamstein modified the milestones: sage-2.9.1, sage-2.8.4.2 Sep 11, 2007
@williamstein
Copy link
Contributor

comment:12

applied for sage-2.8.4.2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant