do you master list comprehensions?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Will Stuyvesant

    #1

    do you master list comprehensions?

    Here is a question about list comprehensions [lc]. The
    question is dumb because I can do without [lc]; but I am
    posing the question because I am curious.

    This:
    [color=blue][color=green][color=darkred]
    >>> data = [['foo','bar','ba z'],['my','your'],['holy','grail']]
    >>> result = []
    >>> for d in data:[/color][/color][/color]
    .... for w in d:
    .... result.append(w )[color=blue][color=green][color=darkred]
    >>> print result[/color][/color][/color]
    ['foo', 'bar', 'baz', 'my', 'your', 'holy', 'grail']

    puts all the words in a list, like I want.

    How to do this with [lc] instead of for-loops?

    I tried funnies like [[w for w in L] for L in data],
    that is correct syntax, but you'd never guess.

    I know, silly! No need for [lc]! So there's my
    question. I am sure a one-liner using [lc] will be very
    enlightening. Like studying LISP.


    --
    I wish there was a knob on the TV to turn up the intelligence.
    There's a knob called `brightness', but it doesn't work.
    -- Gallagher

  • Max M

    #2
    Re: do you master list comprehensions?

    Will Stuyvesant wrote:
    [color=blue]
    > I tried funnies like [[w for w in L] for L in data],
    > that is correct syntax, but you'd never guess.[/color]

    That is absolutely correct. It's not a funnie at all. If you find it odd
    it's only because you are not used to list comprehensiones .

    In that case you might be more comfortable with:

    data = [['foo','bar','ba z'],['my','your'],['holy','grail']]
    result = []
    for l in data:
    result += l


    --

    hilsen/regards Max M, Denmark


    IT's Mad Science

    Comment

    • Steven Bethard

      #3
      Re: do you master list comprehensions?

      Will Stuyvesant wrote:[color=blue][color=green][color=darkred]
      >>>>data = [['foo','bar','ba z'],['my','your'],['holy','grail']]
      >>>>result = []
      >>>>for d in data:[/color][/color]
      >
      > ... for w in d:
      > ... result.append(w )
      >[color=green][color=darkred]
      >>>>print result[/color][/color]
      >
      > ['foo', 'bar', 'baz', 'my', 'your', 'holy', 'grail']
      >[/color]

      Take advantage of the fact that you can have more than one 'for' in a
      list comprehension:
      [color=blue][color=green][color=darkred]
      >>> data = [['foo','bar','ba z'],['my','your'],['holy','grail']]
      >>> [item for item_list in data for item in item_list][/color][/color][/color]
      ['foo', 'bar', 'baz', 'my', 'your', 'holy', 'grail']

      Steve

      Comment

      • Peter Otten

        #4
        Re: do you master list comprehensions?

        Will Stuyvesant wrote:
        [color=blue][color=green][color=darkred]
        >>>> data = [['foo','bar','ba z'],['my','your'],['holy','grail']]
        >>>> result = []
        >>>> for d in data:[/color][/color]
        > ... for w in d:
        > ... result.append(w )[color=green][color=darkred]
        >>>> print result[/color][/color]
        > ['foo', 'bar', 'baz', 'my', 'your', 'holy', 'grail']
        >
        > puts all the words in a list, like I want.
        >
        > How to do this with [lc] instead of for-loops?[/color]
        [color=blue][color=green][color=darkred]
        >>> data = [['foo','bar','ba z'],['my','your'],['holy','grail']]
        >>> [w for d in data for w in d][/color][/color][/color]
        ['foo', 'bar', 'baz', 'my', 'your', 'holy', 'grail']

        See how the for expressions in the list comprehension exactly match your
        nested for loops? That's all there is to it.

        Peter

        Comment

        • Diez B. Roggisch

          #5
          Re: do you master list comprehensions?

          >>> data = [['foo','bar','ba z'],['my','your'],['holy','grail']][color=blue][color=green][color=darkred]
          >>> [e for l in data for e in l][/color][/color][/color]
          ['foo', 'bar', 'baz', 'my', 'your', 'holy', 'grail']
          --
          Regards,

          Diez B. Roggisch

          Comment

          • Fredrik Lundh

            #6
            Re: do you master list comprehensions?

            Max M wrote:
            [color=blue][color=green]
            >> I tried funnies like [[w for w in L] for L in data],
            >> that is correct syntax, but you'd never guess.[/color]
            >
            > That is absolutely correct. It's not a funnie at all. If you find it odd it's only because you are
            > not used to list comprehensiones .[/color]

            well, syntactically correct or not, it doesn't do what he want...
            [color=blue]
            > In that case you might be more comfortable with:
            >
            > data = [['foo','bar','ba z'],['my','your'],['holy','grail']]
            > result = []
            > for l in data:
            > result += l[/color]

            how about (slightly evil):

            result = []; map(result.exte nd, data)

            </F>



            Comment

            • Max M

              #7
              Re: do you master list comprehensions?

              Fredrik Lundh wrote:[color=blue]
              > Max M wrote:
              >
              >[color=green][color=darkred]
              >>>I tried funnies like [[w for w in L] for L in data],[/color]
              >>
              >>That is absolutely correct. It's not a funnie at all.[/color]
              >
              > well, syntactically correct or not, it doesn't do what he want...[/color]

              Doh! *I* might not be used to list comprehensions then... You are right.

              That example could have been expressed more clearly as:

              result = data

              ;-)

              --

              hilsen/regards Max M, Denmark


              IT's Mad Science

              Comment

              • Luis M. Gonzalez

                #8
                Re: do you master list comprehensions?

                I guess the simplest to do it is like this:
                [color=blue][color=green][color=darkred]
                >>> data = [['foo','bar','ba z'],['my','your'],['holy','grail']]
                >>> result=[w for d in data for w in d]
                >>> result[/color][/color][/color]
                ['foo', 'bar', 'baz', 'my', 'your', 'holy', 'grail'][color=blue][color=green][color=darkred]
                >>>[/color][/color][/color]

                Comment

                • Luis M. Gonzalez

                  #9
                  Re: do you master list comprehensions?

                  I guess the simplest way to do it is like this:
                  [color=blue][color=green][color=darkred]
                  >>> data = [['foo','bar','ba z'],['my','your'],['holy','grail']]
                  >>> result=[w for d in data for w in d]
                  >>> result[/color][/color][/color]
                  ['foo', 'bar', 'baz', 'my', 'your', 'holy', 'grail'][color=blue][color=green][color=darkred]
                  >>>[/color][/color][/color]

                  Comment

                  • James Stroud

                    #10
                    Re: do you master list comprehensions?

                    Here is one for arbitrary depth:

                    def unroll(ary):
                    unrolled = []
                    for item in ary:
                    # add test for your favorite sequence type
                    if ( type(item) == types.ListType or \
                    type(item) == types.TupleType \
                    ):
                    unrolled.extend (unroll(item))
                    else:
                    unrolled.append (item)
                    return unrolled


                    [color=blue][color=green][color=darkred]
                    >>> unroll([[1, 2, 3], ('fred', 'barney', ['wilma', 'betty']), 'dino'])[/color][/color][/color]
                    [1, 2, 3, 'fred', 'barney', 'wilma', 'betty', 'dino']




                    On Monday 13 December 2004 12:51 pm, Will Stuyvesant wrote:[color=blue]
                    > Here is a question about list comprehensions [lc]. The
                    > question is dumb because I can do without [lc]; but I am
                    > posing the question because I am curious.
                    >
                    > This:[color=green][color=darkred]
                    > >>> data = [['foo','bar','ba z'],['my','your'],['holy','grail']]
                    > >>> result = []
                    > >>> for d in data:[/color][/color]
                    >
                    > ... for w in d:
                    > ... result.append(w )
                    >[color=green][color=darkred]
                    > >>> print result[/color][/color]
                    >
                    > ['foo', 'bar', 'baz', 'my', 'your', 'holy', 'grail']
                    >
                    > puts all the words in a list, like I want.
                    >
                    > How to do this with [lc] instead of for-loops?
                    >
                    > I tried funnies like [[w for w in L] for L in data],
                    > that is correct syntax, but you'd never guess.
                    >
                    > I know, silly! No need for [lc]! So there's my
                    > question. I am sure a one-liner using [lc] will be very
                    > enlightening. Like studying LISP.[/color]

                    --
                    James Stroud, Ph.D.
                    UCLA-DOE Institute for Genomics and Proteomics
                    611 Charles E. Young Dr. S.
                    MBI 205, UCLA 951570
                    Los Angeles CA 90095-1570

                    Comment

                    • Jeremy Bowers

                      #11
                      Re: do you master list comprehensions?

                      On Tue, 14 Dec 2004 00:41:36 +0100, Max M wrote:
                      [color=blue]
                      > Fredrik Lundh wrote:[color=green]
                      >> Max M wrote:
                      >>
                      >>[color=darkred]
                      >>>>I tried funnies like [[w for w in L] for L in data],
                      >>>
                      >>>That is absolutely correct. It's not a funnie at all.[/color]
                      >>
                      >> well, syntactically correct or not, it doesn't do what he want...[/color]
                      >
                      > Doh! *I* might not be used to list comprehensions then... You are right.
                      >
                      > That example could have been expressed more clearly as:
                      >
                      > result = data[/color]

                      result = data[:]

                      :-)

                      Comment

                      • Fredrik Lundh

                        #12
                        Re: do you master list comprehensions?

                        James Stroud wrote:
                        [color=blue]
                        > Here is one for arbitrary depth:
                        >
                        > def unroll(ary):
                        > unrolled = []
                        > for item in ary:
                        > # add test for your favorite sequence type
                        > if ( type(item) == types.ListType or \
                        > type(item) == types.TupleType \
                        > ):
                        > unrolled.extend (unroll(item))
                        > else:
                        > unrolled.append (item)
                        > return unrolled
                        >[/color]
                        [color=blue][color=green][color=darkred]
                        >>>> unroll([[1, 2, 3], ('fred', 'barney', ['wilma', 'betty']), 'dino'])[/color][/color]
                        > [1, 2, 3, 'fred', 'barney', 'wilma', 'betty', 'dino'][/color]

                        or, shorter:
                        [color=blue][color=green][color=darkred]
                        >>> from Tkinter import _flatten as unroll
                        >>> (1, 2, 3, 'fred', 'wilma', 'betty', 'dino')[/color][/color][/color]

                        (alright, it returns a tuple, but that can be easily fixed, if necessary)

                        </F>



                        Comment

                        • Timothy Babytch

                          #13
                          Re: do you master list comprehensions?

                          Will Stuyvesant wrote:
                          [color=blue][color=green][color=darkred]
                          >>>>data = [['foo','bar','ba z'],['my','your'],['holy','grail']][/color][/color][/color]

                          sum(data, [])

                          ['foo', 'bar', 'baz', 'my', 'your', 'holy', 'grail']

                          The second parameter passed to sum is just to overrride default
                          initial value "zero".

                          --
                          Timothy Babytch

                          Comment

                          • Will Stuyvesant

                            #14
                            Re: do you master list comprehensions?

                            Okay that was fun. Enlightening as I hoped. unroll() in Python, for
                            arbitrary depth, _flatten in Tkinter (what else is in Tkinter!), sum()
                            abuse.

                            The sum(data,[]) was funniest, it works like ((['foo','bar'] + []) +
                            ['my','your']) + ['holy','grail']. Before I think of such things I
                            have already coded an algorithm in imperative style. Guess I have not
                            been exposed to functional programming enough.

                            Comment

                            • Steven Bethard

                              #15
                              Re: do you master list comprehensions?

                              Timothy Babytch wrote:[color=blue]
                              > Will Stuyvesant wrote:
                              >[color=green][color=darkred]
                              >>>>> data = [['foo','bar','ba z'],['my','your'],['holy','grail']][/color][/color]
                              >
                              >
                              > sum(data, [])
                              >
                              > ['foo', 'bar', 'baz', 'my', 'your', 'holy', 'grail']
                              >
                              > The second parameter passed to sum is just to overrride default
                              > initial value "zero".
                              >[/color]

                              It's worth keeping in mind that this solution has the same efficiency
                              problems that a loop that =+ strings does:
                              [color=blue]
                              > python -m timeit -s "data = [range(10) for _ in range(100)]"[/color]
                              "sum(data, [])"
                              1000 loops, best of 3: 530 usec per loop
                              [color=blue]
                              > python -m timeit -s "data = [range(10) for _ in range(100)]" "[w for[/color]
                              d in data for w in d]"
                              10000 loops, best of 3: 151 usec per loop
                              [color=blue]
                              > python -m timeit -s "data = [range(10) for _ in range(1000)]"[/color]
                              "sum(data, [])"
                              10 loops, best of 3: 54.2 msec per loop
                              [color=blue]
                              > python -m timeit -s "data = [range(10) for _ in range(1000)]" "[w for[/color]
                              d in data for w in d]"
                              100 loops, best of 3: 1.75 msec per loop

                              The sum function used in this way (or a loop with a +=) is O(N**2) while
                              the LC is O(N).

                              Steve

                              Comment

                              Working...