is there a better way?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • markscala@gmail.com

    #1

    is there a better way?

    Problem:

    You have a list of unknown length, such as this: list =
    [X,X,X,O,O,O,O]. You want to extract all and only the X's. You know
    the X's are all up front and you know that the item after the last X is
    an O, or that the list ends with an X. There are never O's between
    X's.

    I have been using something like this:
    _______________ ______

    while list[0] != O:
    storage.append( list[0])
    list.pop(0)
    if len(list) == 0:
    break
    _______________ ______

    But this seems ugly to me, and using "while" give me the heebies. Is
    there a better approach?

    hope this is clear.
    thanks

  • Jeremy Sanders

    #2
    Re: is there a better way?

    markscala@gmail .com wrote:
    [color=blue]
    > You have a list of unknown length, such as this: list =
    > [X,X,X,O,O,O,O]. You want to extract all and only the X's. You know
    > the X's are all up front and you know that the item after the last X is
    > an O, or that the list ends with an X. There are never O's between
    > X's.[/color]

    What not

    for x in list:
    if x == O:
    break
    storage.append( x)

    ??

    --
    Jeremy Sanders

    Comment

    • snoe

      #3
      Re: is there a better way?


      markscala@gmail .com wrote:[color=blue]
      > Problem:
      >
      > You have a list of unknown length, such as this: list =
      > [X,X,X,O,O,O,O]. You want to extract all and only the X's. You know
      > the X's are all up front and you know that the item after the last X is
      > an O, or that the list ends with an X. There are never O's between
      > X's.
      >
      > I have been using something like this:
      > _______________ ______
      >
      > while list[0] != O:
      > storage.append( list[0])
      > list.pop(0)
      > if len(list) == 0:
      > break
      > _______________ ______
      >
      > But this seems ugly to me, and using "while" give me the heebies. Is
      > there a better approach?
      >
      > hope this is clear.
      > thanks[/color]


      There's a few ways to do this, really depends on :

      mylist = [1,2,3,4,5,6,0,0 ,0]

      list comprehension (will get ALL non zeros, and strip out all zeros,
      but is different from your function):
      [x for x in mylist if x != 0]

      list slice(same as your function):
      mylist[:mylist.index(0 )]

      Depends what you want to happen if your list is something like:
      [1,2,3,0,4,5,6,0 ,0]
      [0,1,2,3,4,5,6]
      [0,1,2,3,4,5,6,0]
      [1,2,3,4,5,6]

      Comment

      • Paul McGuire

        #4
        Re: is there a better way?

        <markscala@gmai l.com> wrote in message
        news:1139594221 .696053.7360@g4 7g2000cwa.googl egroups.com...[color=blue]
        > Problem:
        >
        > You have a list of unknown length, such as this: list =
        > [X,X,X,O,O,O,O]. You want to extract all and only the X's. You know
        > the X's are all up front and you know that the item after the last X is
        > an O, or that the list ends with an X. There are never O's between
        > X's.
        >
        > I have been using something like this:
        > _______________ ______
        >
        > while list[0] != O:
        > storage.append( list[0])
        > list.pop(0)
        > if len(list) == 0:
        > break
        > _______________ ______
        >
        > But this seems ugly to me, and using "while" give me the heebies. Is
        > there a better approach?
        >
        > hope this is clear.
        > thanks
        >[/color]
        Use itertools.
        [color=blue][color=green][color=darkred]
        >>> import itertools
        >>> lst = "X,X,X,O,O,O,O, O,X,X,X,X,O,X". split(",")
        >>> [z for z in itertools.takew hile(lambda x:x=="X",lst)][/color][/color][/color]
        ['X', 'X', 'X']


        -- Paul


        Comment

        • Tim Chase

          #5
          Re: is there a better way?

          > You have a list of unknown length, such as this: list =[color=blue]
          > [X,X,X,O,O,O,O]. You want to extract all and only the X's. You know
          > the X's are all up front and you know that the item after the last X is
          > an O, or that the list ends with an X. There are never O's between
          > X's.
          >
          > I have been using something like this:
          > _______________ ______
          >
          > while list[0] != O:
          > storage.append( list[0])
          > list.pop(0)
          > if len(list) == 0:
          > break
          > _______________ ______[/color]

          While it doesn't modify your list, you can try something like

          storage = [q for q in myList if q != O]

          If you've already got stuff in storage that you want to keep, you
          can use

          storage.extend([q for q in myList if q != O])

          I suppose, if you wanted to remove all the O's, you could then
          just do

          myList = [q for q in myList if q == O]

          (trickiness using Oh's vs. using zeros...)

          -tkc






          Comment

          • Paul McGuire

            #6
            Re: is there a better way?

            "Paul McGuire" <ptmcg@austin.r r._bogus_.com> wrote in message
            news:PO4Hf.4221 $UN2.1478@torna do.texas.rr.com ...[color=blue]
            > <markscala@gmai l.com> wrote in message
            > news:1139594221 .696053.7360@g4 7g2000cwa.googl egroups.com...[color=green]
            > > Problem:
            > >
            > > You have a list of unknown length, such as this: list =
            > > [X,X,X,O,O,O,O]. You want to extract all and only the X's. You know
            > > the X's are all up front and you know that the item after the last X is
            > > an O, or that the list ends with an X. There are never O's between
            > > X's.
            > >
            > > I have been using something like this:
            > > _______________ ______
            > >
            > > while list[0] != O:
            > > storage.append( list[0])
            > > list.pop(0)
            > > if len(list) == 0:
            > > break
            > > _______________ ______
            > >
            > > But this seems ugly to me, and using "while" give me the heebies. Is
            > > there a better approach?
            > >
            > > hope this is clear.
            > > thanks
            > >[/color]
            > Use itertools.
            >[color=green][color=darkred]
            > >>> import itertools
            > >>> lst = "X,X,X,O,O,O,O, O,X,X,X,X,O,X". split(",")
            > >>> [z for z in itertools.takew hile(lambda x:x=="X",lst)][/color][/color]
            > ['X', 'X', 'X']
            >
            >
            > -- Paul
            >[/color]

            duh, last line should be:
            [color=blue][color=green][color=darkred]
            >>> list(itertools. takewhile(lambd a x:x=="X",lst))[/color][/color][/color]
            ['X', 'X', 'X']

            (Also, don't name variables "list")

            -- Paul


            Comment

            • Scott David Daniels

              #7
              Re: is there a better way?

              markscala@gmail .com wrote:[color=blue]
              > Problem:
              >
              > You have a list of unknown length, such as this: list =
              > [X,X,X,O,O,O,O]. You want to extract all and only the X's. You know
              > the X's are all up front and you know that the item after the last X is
              > an O, or that the list ends with an X. There are never O's between
              > X's.
              >
              > I have been using something like this:
              > while list[0] != O:
              > storage.append( list[0])
              > list.pop(0)
              > if len(list) == 0:
              > break
              > But this seems ugly to me, and using "while" give me the heebies. Is
              > there a better approach?
              >[/color]

              Your names could be better as someone mentioned.
              ex, oh = 7, 13 # for example
              data = [ex, ex, ex, oh, oh, oh, oh]
              If you need a list distinct from the original:
              try:
              result = data[: data.index(oh)]
              except ValueError:
              result = list(data)

              Or you could simply:
              try:
              data = data[: data.index(oh)]
              except ValueError:
              pass
              and data will be either the sublist you want or the original list.

              --
              -Scott David Daniels
              scott.daniels@a cm.org

              Comment

              • Schüle Daniel

                #8
                Re: is there a better way?

                [...]
                [color=blue]
                >
                > What not
                >
                > for x in list:
                > if x == O:
                > break
                > storage.append( x)
                >[/color]

                i think this may take too long
                better aproach would be to test for zero from the end

                Regards, Daniel

                Comment

                • Schüle Daniel

                  #9
                  Re: is there a better way?

                  [...]
                  [color=blue]
                  > I have been using something like this:
                  > _______________ ______
                  >
                  > while list[0] != O:
                  > storage.append( list[0])
                  > list.pop(0)
                  > if len(list) == 0:
                  > break
                  > _______________ ______
                  >
                  > But this seems ugly to me, and using "while" give me the heebies. Is
                  > there a better approach?[/color]
                  [color=blue][color=green][color=darkred]
                  >>> lst = [1,2,3,4,5,0,0,0 ,0]
                  >>> del lst[lst.index(0):]
                  >>> lst[/color][/color][/color]
                  [1, 2, 3, 4, 5][color=blue][color=green][color=darkred]
                  >>>[/color][/color][/color]

                  Regards, Daniel

                  Comment

                  • Lonnie Princehouse

                    #10
                    Re: is there a better way?

                    everybody is making this way more complicated than it needs to be.

                    storage = list[:list.index(O)]

                    incidentally, "list" is the name of a type, so you might want to avoid
                    using it as a variable name.

                    Comment

                    • Jeremy Dillworth

                      #11
                      Re: is there a better way?

                      You could eliminate a few lines like this:

                      -----------------------------
                      while list and list[0] != O:
                      storage.append( list.pop(0))
                      -----------------------------

                      Adding the "list and " to the front of the logic test will catch when
                      there are 0 elements, so the "if..break" lines are not needed. Also
                      pop() returns the element popped, so there's no need for a separate
                      "list[0]" and "list.pop(0 )"

                      You could also do the whole thing as a list comprehension (assuming
                      storage is a list, otherwise += may or may not work):
                      -----------------------------
                      storage += [i for i in list if i == X]
                      -----------------------------

                      But this is less efficient, since it will loop through all the O's too.
                      The other solution stops at the first O. This will also break if
                      there are any X's mixed with O's, though you've said that's not
                      currently the case, things can always change.

                      Lastly, you could do this:
                      -----------------------------
                      list.append(O)
                      storage += list[:list.index(O)]
                      -----------------------------

                      The first line makes sure there is always an O in list, otherwise
                      index(O) will throw an exception. That's slightly ugly, but I still
                      like this solution, myself.

                      hope this helps,

                      Jeremy

                      Comment

                      • Schüle Daniel

                        #12
                        Re: is there a better way?

                        Lonnie Princehouse wrote:[color=blue]
                        > everybody is making this way more complicated than it needs to be.
                        >
                        > storage = list[:list.index(O)][/color]

                        the question is whether the old list is needed in the future or not
                        if not then it would be easer/mor efficient to use

                        del lst[lst.index(0):]

                        Regards, Daniel

                        Comment

                        • Schüle Daniel

                          #13
                          Re: is there a better way?

                          I don't want to hijack the thread I was thinking
                          whether something like lst.remove(item = 0, all = True)
                          would be worth adding to Python?

                          it could have this signature

                          def remove(item, nItems = 1, all = False)
                          ...
                          return how_many_delete d

                          lst.remove(item = 0, nItems = 1)
                          lst.remove(item = 0, nItems = 2)

                          lst.remove(item = 0, all = True)
                          in last case nItems is ignored

                          Regards, Daniel

                          Comment

                          • Scott David Daniels

                            #14
                            Re: is there a better way?

                            Scott David Daniels wrote:[color=blue]
                            > markscala@gmail .com wrote:[color=green]
                            >> Problem:
                            >>
                            >> You have a list of unknown length, such as this: list =
                            >> [X,X,X,O,O,O,O]. You want to extract all and only the X's. You know
                            >> the X's are all up front and you know that the item after the last X is
                            >> an O, or that the list ends with an X. There are never O's between
                            >> X's.
                            >>
                            >> I have been using something like this:
                            >> while list[0] != O:
                            >> storage.append( list[0])
                            >> list.pop(0)
                            >> if len(list) == 0:
                            >> break
                            >> But this seems ugly to me, and using "while" give me the heebies. Is
                            >> there a better approach?
                            >>[/color]
                            >
                            > Your names could be better as someone mentioned.
                            > ex, oh = 7, 13 # for example
                            > data = [ex, ex, ex, oh, oh, oh, oh]
                            > If you need a list distinct from the original:
                            > try:
                            > result = data[: data.index(oh)]
                            > except ValueError:
                            > result = list(data)
                            >
                            > Or you could simply:
                            > try:
                            > data = data[: data.index(oh)]
                            > except ValueError:
                            > pass
                            > and data will be either the sublist you want or the original list.[/color]

                            I forgot the obvious:

                            result = data.count(ex) * [ex]

                            --
                            -Scott David Daniels
                            scott.daniels@a cm.org

                            Comment

                            • Dave Hansen

                              #15
                              Re: is there a better way?

                              On Sat, 11 Feb 2006 01:37:59 +0100 in comp.lang.pytho n, Schüle Daniel
                              <uval@rz.uni-karlsruhe.de> wrote:
                              [color=blue]
                              >Lonnie Princehouse wrote:[color=green]
                              >> everybody is making this way more complicated than it needs to be.
                              >>
                              >> storage = list[:list.index(O)][/color]
                              >
                              >the question is whether the old list is needed in the future or not
                              >if not then it would be easer/mor efficient to use
                              >
                              >del lst[lst.index(0):][/color]

                              And you're both forgetting the list can end with X. the index method
                              raises a ValueError exception if the desired value is not found in the
                              list. Assuming you want to keep the original list and create a new
                              list called storage, you could try

                              if lst[-1] == X:
                              storage = lst[:]
                              else:
                              storage = lst[:lst.index(O)]

                              or even

                              try:
                              storage = lst[:lst.index(O)]
                              except ValueError:
                              storage = lst[:]

                              (WARNING: untested!)

                              Regards,



                              -=Dave

                              --
                              Change is inevitable, progress is not.

                              Comment

                              Working...