interleaving dictionary values

Discussion in 'Python' started by j1o1h1n@gmail.com, Nov 21, 2006.

  1. Guest

    Hello,

    I was trying to create a flattened list of dictionary values where each
    value is a list, and I was hoping to do this in some neat functionally
    style, in some brief, throwaway line so that it would assume the
    insignificance that it deserves in the grand scheme of my program.

    I had in mind something like this:

    >>> interleave([1, 2, 3], [4,5], [7, 8, 9])

    [1, 4, 7, 2, 5, 8, 3, 9]

    I played for a while with zip(), [some newfangled python keyword, that
    I was truly shocked to find has been hiding at the bottom of the list
    built in functions since version 2.0], before giving up and going back
    to trusty old map(), long celebrated for making code hard to read:

    >>> map(None, [1, 2, 3], [4,5], [7, 8, 9])

    [(1, 4, 7), (2, 5, 8), (3, None, 9)]

    This is basically it. It then becomes:

    >>> filter(None, flatten(map(None, [1, 2, 3], [4,5], [7, 8, 9])))

    [1, 4, 7, 2, 5, 8, 3, 9]

    filter(None, - my brain parses that automatically now. This is not so
    bad. Flatten is snitched from ASPN/Cookbook/Python/Recipe/363051,
    thank you Jordan Callicoat, Mike C. Fletcher:

    def flatten(l, ltypes=(list, tuple)):
    i = 0
    while (i < len(l)):
    while (isinstance(l, ltypes)):
    l[i:i+1] = list(l)
    i += 1
    return l

    Trouble is then getting map() to play with the result of dict.values().
    I only worked this out while writing this post, of course.

    Given a dictionary like d = { "a" : [1, 2, 3], "b" : [4, 5], "c" : [7,
    8, 9]} - I was hoping to do this:

    map(None, d.values())

    But instead I (finally worked out I could) do this:

    apply(map, tuple([None] + d.values()))

    So... my bit of code becomes:

    filter(None, flatten(map(None, apply(map, tuple([None] +
    d.values())))))

    It fits on one line, but it feels far more evil than I set out to be.
    The brackets at the end are bad for my epilepsy.

    Surely there is there some nice builtin function I have missed?

    --
    | John J. Lehmann, j1o1h1n(@)gmail.com
    + [lost-in-translation] "People using public transport look stern, and
    handbag
    + snatchers increase the ill feeling." A Japanese woman, Junko, told
    the paper:
    + "For us, Paris is the dream city. The French are all beautiful and
    elegant
    + And then, when we arrive..."
     
    , Nov 21, 2006
    #1
    1. Advertising

  2. wrote:
    [...]
    > I had in mind something like this:
    >
    >>>> interleave([1, 2, 3], [4,5], [7, 8, 9])

    > [1, 4, 7, 2, 5, 8, 3, 9]


    [...]
    > But instead I (finally worked out I could) do this:
    >
    > apply(map, tuple([None] + d.values()))


    apply is deprecated, it should be map(None, *d.values())

    > So... my bit of code becomes:
    >
    > filter(None, flatten(map(None, apply(map, tuple([None] +
    > d.values())))))
    >
    > It fits on one line, but it feels far more evil than I set out to be.
    > The brackets at the end are bad for my epilepsy.
    >
    > Surely there is there some nice builtin function I have missed?


    You have missed the "it doesn't need to be a one-liner" motto :)

    >>> def interleave(*args):

    .... result = []
    .... for items in map(None, *args):
    .... result.extend([x for x in items if x is not None])
    .... return result
    ....
    >>> interleave([1, 2, 3], [4,5], [7, 8, 9])

    [1, 4, 7, 2, 5, 8, 3, 9]

    Cheers,
    --
    Roberto Bonvallet
     
    Roberto Bonvallet, Nov 21, 2006
    #2
    1. Advertising

  3. Neil Cerutti Guest

    On 2006-11-21, <> wrote:
    > I had in mind something like this:
    >
    >>>> interleave([1, 2, 3], [4,5], [7, 8, 9])

    > [1, 4, 7, 2, 5, 8, 3, 9]
    >
    > [...] before giving up and going back to trusty old map(), long
    > celebrated for making code hard to read:
    >
    >>>> map(None, [1, 2, 3], [4,5], [7, 8, 9])

    > [(1, 4, 7), (2, 5, 8), (3, None, 9)]
    >
    > This is basically it. It then becomes:
    >
    >>>> filter(None, flatten(map(None, [1, 2, 3], [4,5], [7, 8, 9])))

    > [1, 4, 7, 2, 5, 8, 3, 9]


    You can use itertools.chain instead of flatten:

    >>> from itertools import chain
    >>> filter(None, chain(*map(None, [1, 2, 3], [4, 5], [7, 8, 9])))

    [1, 4, 7, 2, 5, 8, 3, 9]

    > Trouble is then getting map() to play with the result of dict.values().
    > I only worked this out while writing this post, of course.
    >
    > Given a dictionary like d = { "a" : [1, 2, 3], "b" : [4, 5], "c" : [7,
    > 8, 9]} - I was hoping to do this:
    >
    > map(None, d.values())


    You need the * to "unpack" the list. It has generally taken the
    place of apply.

    >>> map(None, *d.values())

    [(1, 7, 4), (2, 8, 5), (3, 9, None)]

    > So... my bit of code becomes:


    >>> filter(None, chain(*map(None, *d.values())))

    [1, 7, 4, 2, 8, 5, 3, 9]

    I don't think that the specific ordering that's achieved has any
    valuable significance. You might be just as happy with the
    simpler:

    >>> list(chain(*d.values()))

    [1, 2, 3, 7, 8, 9, 4, 5]

    --
    Neil Cerutti
    Weight Watchers will meet at 7 p.m. Please use large double door at the side
    entrance. --Church Bulletin Blooper
     
    Neil Cerutti, Nov 21, 2006
    #3
  4. Guest

    d = {"a": [1, 2, 3], "b": [4, 5], "c": [7, 8, 9]}

    # Simple solution:
    result = []
    for l in d.itervalues():
    result.extend(l)
    print result

    # Alternative:
    from itertools import chain
    print list( chain(*d.itervalues()) )

    I don't know what's the faster solution, the first one seem more
    readable and it's probably fast enough.

    Bye,
    bearophile
     
    , Nov 21, 2006
    #4
  5. Noah Rawlins Guest

    wrote:

    > filter(None, - my brain parses that automatically now. This is not so
    > bad. Flatten is snitched from ASPN/Cookbook/Python/Recipe/363051,
    > thank you Jordan Callicoat, Mike C. Fletcher:
    >
    > def flatten(l, ltypes=(list, tuple)):
    > i = 0
    > while (i < len(l)):
    > while (isinstance(l, ltypes)):
    > l[i:i+1] = list(l)
    > i += 1
    > return l
    >


    On a side note, that version of flatten doesn't handle an empty list as
    the last element of a list...

    >>> flatten([1, 2, 3, []])

    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "<stdin>", line 4, in flatten
    IndexError: list index out of range

    You need a try: in there or something...

    def flatten(l, ltypes=(list, tuple)):
    i = 0
    while(i < len(l)):
    try:
    while(isinstance(l, ltypes)):
    l[i:i+1] = list(l)
    i += 1
    except IndexError:
    pass
    return l

    noah
     
    Noah Rawlins, Nov 22, 2006
    #5
  6. Tuomas Guest

    wrote:
    > Hello,
    >
    > I was trying to create a flattened list of dictionary values where each
    > value is a list, and I was hoping to do this in some neat functionally
    > style, in some brief, throwaway line so that it would assume the
    > insignificance that it deserves in the grand scheme of my program.
    >
    > I had in mind something like this:
    >
    >
    >>>>interleave([1, 2, 3], [4,5], [7, 8, 9])

    >
    > [1, 4, 7, 2, 5, 8, 3, 9]
    >
    > I played for a while with zip(), [some newfangled python keyword, that
    > I was truly shocked to find has been hiding at the bottom of the list
    > built in functions since version 2.0], before giving up and going back
    > to trusty old map(), long celebrated for making code hard to read:
    >
    >
    >>>>map(None, [1, 2, 3], [4,5], [7, 8, 9])

    >
    > [(1, 4, 7), (2, 5, 8), (3, None, 9)]
    >
    > This is basically it. It then becomes:
    >
    >
    >>>>filter(None, flatten(map(None, [1, 2, 3], [4,5], [7, 8, 9])))

    >
    > [1, 4, 7, 2, 5, 8, 3, 9]
    >
    > filter(None, - my brain parses that automatically now. This is not so
    > bad. Flatten is snitched from ASPN/Cookbook/Python/Recipe/363051,
    > thank you Jordan Callicoat, Mike C. Fletcher:
    >
    > def flatten(l, ltypes=(list, tuple)):
    > i = 0
    > while (i < len(l)):
    > while (isinstance(l, ltypes)):
    > l[i:i+1] = list(l)
    > i += 1
    > return l
    >
    > Trouble is then getting map() to play with the result of dict.values().
    > I only worked this out while writing this post, of course.
    >
    > Given a dictionary like d = { "a" : [1, 2, 3], "b" : [4, 5], "c" : [7,
    > 8, 9]} - I was hoping to do this:
    >
    > map(None, d.values())
    >
    > But instead I (finally worked out I could) do this:
    >
    > apply(map, tuple([None] + d.values()))
    >
    > So... my bit of code becomes:
    >
    > filter(None, flatten(map(None, apply(map, tuple([None] +
    > d.values())))))
    >
    > It fits on one line, but it feels far more evil than I set out to be.
    > The brackets at the end are bad for my epilepsy.
    >
    > Surely there is there some nice builtin function I have missed?
    >
    > --
    > | John J. Lehmann, j1o1h1n(@)gmail.com
    > + [lost-in-translation] "People using public transport look stern, and
    > handbag
    > + snatchers increase the ill feeling." A Japanese woman, Junko, told
    > the paper:
    > + "For us, Paris is the dream city. The French are all beautiful and
    > elegant
    > + And then, when we arrive..."
    >


    What about:
    >>> d = { "a" : [1, 2, 3], "b" : [4, 5], "c" : [7, 8, 9]}
    >>> L=[]
    >>> for x in d.values(): L.extend(x)

    ....
    >>> L

    [1, 2, 3, 7, 8, 9, 4, 5]

    or a little curious:
    >>> L=[]
    >>> map(L.extend, d.values())

    [None, None, None]
    >>> L

    [1, 2, 3, 7, 8, 9, 4, 5]

    TV
     
    Tuomas, Nov 22, 2006
    #6
    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. Tom Plunket

    any such thing as list interleaving?

    Tom Plunket, Jul 12, 2003, in forum: Python
    Replies:
    2
    Views:
    398
    Gonçalo Rodrigues
    Jul 12, 2003
  2. Ilias Lazaridis
    Replies:
    6
    Views:
    446
    Ilias Lazaridis
    Feb 21, 2006
  3. Replies:
    1
    Views:
    432
  4. Giulio

    1024 bites interleaving frequency???

    Giulio, Nov 24, 2004, in forum: C Programming
    Replies:
    7
    Views:
    407
    Richard Tobin
    Nov 25, 2004
  5. Garrett Kajmowicz

    Interleaving iostream read and write

    Garrett Kajmowicz, Aug 14, 2005, in forum: C++
    Replies:
    0
    Views:
    457
    Garrett Kajmowicz
    Aug 14, 2005
Loading...

Share This Page