flattening and rebuilding a simple list of lists

Discussion in 'Python' started by Esmail, Nov 30, 2009.

  1. Esmail

    Esmail Guest

    Hi,

    I have a list of lists. The number of sublists may vary. The sizes of
    the sublists may also vary. For instance, here I have a list with 3
    sublists of differing sizes.

    [['a', 'b', 'c'], ['d', 'e'], ['f', 'g', 'h', 'i']]

    This list will never be any deeper than this one level.

    What I would like to do is flatten this list, rearrange the items in
    the new flattened list and then recreate the list of sublists with the
    new content. I would like the sublists to have the same size and order
    (relative to each other) as before.

    My code below seems to work, but it feels a bit "hack'ish", and I
    am concerned about efficiency - so I would appreciate suggestions.

    Again, the number of sublists may vary, and sizes of sublists are not
    always the same (there will always be at least one sublist).

    thanks!

    Esmail

    Here is my working code so far.

    ----------------

    #!/usr/bin/env python

    from random import shuffle

    ##################################################################
    def flatten_list(parts):
    """ flatten parts, and return index vals where to split """

    line = sum(parts, []) # join all parts into one

    idx_vals = []
    idx = 0

    for item in parts: # keep track of lengths/index values
    idx += len(item)
    idx_vals.append(idx)

    return line, idx_vals



    ##################################################################
    def rebuilt_lists(line, idx):
    """ rebuild list of list """

    new_list = [line[0:idx[0]]]

    for i in xrange(len(idx)-1):
    new_list.append(line[idx:idx[i+1]])

    return new_list






    ##################################################################
    def main():
    indi = [['a', 'b', 'c'], ['d', 'e'], ['f', 'g', 'h', 'i']]
    print 'indi :', indi


    # flatten list of list
    new_indi, idx_vals = flatten_list(indi)
    print 'new_indi:', new_indi
    print 'lengths :', idx_vals
    print

    # manipulate list
    print 'shuffling new_indi'
    shuffle(new_indi)
    print 'new_indi:', new_indi
    print

    # rebuild list of lists
    new_list = rebuilt_lists(new_indi, idx_vals)
    print 'new_list:', new_list

    if __name__ == '__main__':
    main()
     
    Esmail, Nov 30, 2009
    #1
    1. Advertising

  2. Esmail

    Peter Otten Guest

    Esmail wrote:

    > Hi,
    >
    > I have a list of lists. The number of sublists may vary. The sizes of
    > the sublists may also vary. For instance, here I have a list with 3
    > sublists of differing sizes.
    >
    > [['a', 'b', 'c'], ['d', 'e'], ['f', 'g', 'h', 'i']]
    >
    > This list will never be any deeper than this one level.
    >
    > What I would like to do is flatten this list, rearrange the items in
    > the new flattened list and then recreate the list of sublists with the
    > new content. I would like the sublists to have the same size and order
    > (relative to each other) as before.
    >
    > My code below seems to work, but it feels a bit "hack'ish", and I
    > am concerned about efficiency - so I would appreciate suggestions.


    I don't think it's hackish, but here's an alternative:

    >>> items = [['a', 'b', 'c'], ['d', 'e'], ['f', 'g', 'h', 'i']]
    >>> flat = sum(items, [])
    >>> flat.reverse()
    >>> from itertools import imap, islice
    >>> flat = iter(flat)
    >>> [list(islice(flat, size)) for size in imap(len, items)]

    [['i', 'h', 'g'], ['f', 'e'], ['d', 'c', 'b', 'a']]

    Peter
     
    Peter Otten, Nov 30, 2009
    #2
    1. Advertising

  3. Esmail

    Neil Cerutti Guest

    On 2009-11-30, Esmail <> wrote:
    > I have a list of lists. The number of sublists may vary. The
    > sizes of the sublists may also vary. For instance, here I have
    > a list with 3 sublists of differing sizes.
    >
    > [['a', 'b', 'c'], ['d', 'e'], ['f', 'g', 'h', 'i']]
    >
    > This list will never be any deeper than this one level.
    >
    > What I would like to do is flatten this list, rearrange the
    > items in the new flattened list and then recreate the list of
    > sublists with the new content. I would like the sublists to
    > have the same size and order (relative to each other) as
    > before.


    Depending on your usage pattern, directly mutating the original
    through a simple "view" might be a viable alternative:

    def set_flattened(lst, i, val):
    j = 0
    while i >= len(lst[j]):
    i -= len(lst[j])
    j += 1
    lst[j] = val

    def get_flattened(lst, i):
    j = 0
    while i >= len(lst[j]):
    i -= len(lst[j])
    j += 1
    return lst[j]

    A "view" should be easier to use and debug than your current
    flatten, mutate and unflatten approach.

    The above functions obviously make the maximum number of
    assumptions about your data structures, and currently don't work
    sensibly with negative indices.

    --
    Neil Cerutti
     
    Neil Cerutti, Nov 30, 2009
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. delgados129
    Replies:
    2
    Views:
    814
    delgados129
    Apr 25, 2005
  2. David Gersic

    Flattening out an XML document

    David Gersic, May 24, 2005, in forum: XML
    Replies:
    0
    Views:
    414
    David Gersic
    May 24, 2005
  3. gangesmaster

    a flattening operator?

    gangesmaster, Apr 18, 2006, in forum: Python
    Replies:
    2
    Views:
    314
    Michael Tobis
    Apr 22, 2006
  4. =?UTF-8?B?w4FuZ2VsIEd1dGnDqXJyZXogUm9kcsOtZ3Vleg==

    List of lists of lists of lists...

    =?UTF-8?B?w4FuZ2VsIEd1dGnDqXJyZXogUm9kcsOtZ3Vleg==, May 8, 2006, in forum: Python
    Replies:
    5
    Views:
    448
    =?UTF-8?B?w4FuZ2VsIEd1dGnDqXJyZXogUm9kcsOtZ3Vleg==
    May 15, 2006
  5. mk

    Flattening lists

    mk, Feb 5, 2009, in forum: Python
    Replies:
    21
    Views:
    788
Loading...

Share This Page