different ways to creating two lists from one

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Todd MacCulloch

    different ways to creating two lists from one

    Suppose I have a master list and I need to create two derived lists,
    something like:

    s0 = [2,3,4]
    s1 = [x + x for x in s0]
    s2 = [x * x for x in s0]

    But suppose generating s0 is expensive and/or s0 is big. In otherwords I'd
    like to go over only once and I don't want to keep it around any longer than
    I have to.

    I could do something like:

    for a, b in [(x + x, x * x) for x in s0]:
    s1.append(a)
    s2.append(b)

    Is there a better / cleaner way that I'm missing?



  • Diez B. Roggisch

    #2
    Re: different ways to creating two lists from one

    > But suppose generating s0 is expensive and/or s0 is big. In otherwords I'd[color=blue]
    > like to go over only once and I don't want to keep it around any longer
    > than I have to.
    >
    > I could do something like:
    >
    > for a, b in [(x + x, x * x) for x in s0]:
    > s1.append(a)
    > s2.append(b)
    >
    > Is there a better / cleaner way that I'm missing?[/color]

    Why the uneccessary list comprehension? That makes only sense if you want to
    actually keep it. Which you say you don't want :)

    So simply

    for x in s0:
    s1.append(2*x)
    s2.append(x*x)

    should do the trick. Especially if s0 itselft is an iterator.

    Diez

    Comment

    • Alex Martelli

      #3
      Re: different ways to creating two lists from one

      Todd MacCulloch wrote:
      [color=blue]
      > Suppose I have a master list and I need to create two derived lists,
      > something like:
      >
      > s0 = [2,3,4]
      > s1 = [x + x for x in s0]
      > s2 = [x * x for x in s0]
      >
      > But suppose generating s0 is expensive and/or s0 is big. In otherwords I'd
      > like to go over only once and I don't want to keep it around any longer
      > than I have to.
      >
      > I could do something like:
      >
      > for a, b in [(x + x, x * x) for x in s0]:
      > s1.append(a)
      > s2.append(b)
      >
      > Is there a better / cleaner way that I'm missing?[/color]

      Try timing your solutions, with an s0 as long as you want: I would be
      very surprised if the first approach wasn't faster than the second one.

      Assuming it's impossible to loop repeatedly on s0 AND the thing is too
      huge to store anywhere, you can turn a sequence of pairs into a pair
      of sequences with zip(*seqofpairs ), but, again, you should measure
      the speed rather than assuming the "cool" solution is fast:-).


      Alex

      Comment

      • Fredrik Lundh

        #4
        Re: different ways to creating two lists from one

        Todd MacCulloch wrote:
        [color=blue]
        > But suppose generating s0 is expensive and/or s0 is big. In otherwords I'd
        > like to go over only once and I don't want to keep it around any longer than
        > I have to.
        >
        > I could do something like:
        >
        > for a, b in [(x + x, x * x) for x in s0]:
        > s1.append(a)
        > s2.append(b)[/color]

        ouch.
        [color=blue]
        > Is there a better / cleaner way that I'm missing?[/color]

        for x in s0:
        s1.append(x + x)
        s2.append(x * x)
        del s0

        (memorywise, that's no better than your first alternative.
        it's a better than your second alternative, though...)

        if s0 contains large and ugly things, you could do something
        like this:

        for i, x in enumerate(s0):
        s1.append(x + x)
        s2.append(x * x)
        s0[i] = None

        </F>




        Comment

        Working...