Problem with the sort() function

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

    #1

    Problem with the sort() function

    Hi,

    I have an array of arrays in the form of
    list = [[3,'fork',0.3,1],[2,'fork,0.1,2],[3,'exec',0.2,2]]

    The in-built sort(),list.sor t() sorts on the first element, if the first
    elts are equal then it sorts on the second elt and so on...But i really
    dont want to search on the second elt if the first elts are equal...the
    1-D lists shud be left in the same position i.e. i want the sorted list to
    be [[2,'fork',0.1,2],[3,'fork,0.3,1],[3,'exec',0.2,2]] and not
    [[2,'fork',0.1,2],[3,'exec',0.2,2],[3,'fork,0.3,1]].

    I tried the following code:

    def mysort(x,y):
    return x[0]-y[0]

    list.sort(mysor t)

    This somehow seems to work for a small subset of my input...but not for my
    real input which has more than 2000 sub-lists(and so obviously i cant trace
    each pass..). Can someone tell me what i'm missing?


  • Nick Coghlan

    #2
    Re: Problem with the sort() function

    clementine wrote:[color=blue]
    > Hi,
    >
    > I have an array of arrays in the form of
    > list = [[3,'fork',0.3,1],[2,'fork,0.1,2],[3,'exec',0.2,2]]
    >
    > The in-built sort(),list.sor t() sorts on the first element, if the first
    > elts are equal then it sorts on the second elt and so on...But i really
    > dont want to search on the second elt if the first elts are equal...the
    > 1-D lists shud be left in the same position i.e. i want the sorted list to
    > be [[2,'fork',0.1,2],[3,'fork,0.3,1],[3,'exec',0.2,2]] and not
    > [[2,'fork',0.1,2],[3,'exec',0.2,2],[3,'fork,0.3,1]].[/color]

    Try this:

    Py> from operator import itemgetter
    Py> list = [[3,'fork',0.3,1],[2,'fork',0.1,2],[3,'exec',0.2,2]]
    Py> list.sort(key=i temgetter(0))
    Py> list
    [[2, 'fork', 0.1000000000000 0001, 2], [3, 'fork', 0.2999999999999 9999, 1], [3, '
    exec', 0.2000000000000 0001, 2]]

    If the 'key' argument isn't accepted (i.e. you aren't using Python 2.4), you'll
    need to do the decoration manually:

    def mysort(iterable , cmp=None, key=None, reverse=False):
    "return a sorted copy of its input"
    if sys.version_inf o >= (2,4):
    return sorted(iterable , cmp, key, reverse)
    seq = list(iterable)
    if reverse:
    seq.reverse() # preserve stability
    if key is not None:
    seq = [(key(elem), i, elem) for i, elem in enumerate(seq)]
    seq.sort(cmp)
    if key is not None:
    seq = [elem for (key, i, elem) in seq]
    if reverse:
    seq.reverse()
    return seq

    list = mysort([[3,'fork',0.3,1],[2,'fork',0.1,2],[3,'exec',0.2,2]],
    key=lambda x: x[0])

    (Taken from Raymond's code in:
    http://mail.python.org/pipermail/pyt...ry/263275.html)

    Cheers,
    Nick.

    --
    Nick Coghlan | ncoghlan@email. com | Brisbane, Australia
    ---------------------------------------------------------------

    Comment

    • clementine

      #3
      Re: Problem with the sort() function

      Thanx Nick...I forgot to mention im using python 2.2 and along with a host
      of other things it doesnt seem to have the enumarate built in function
      :(:(:(...is it possible to replace it by something else? I dont think
      simulating it will be feasible....

      Comment

      • Sion Arrowsmith

        #4
        Re: Problem with the sort() function

        clementine <kashmira_v_pha lak@yahoo.com> wrote:[color=blue]
        >Thanx Nick...I forgot to mention im using python 2.2 and along with a host
        >of other things it doesnt seem to have the enumarate built in function
        >:(:(:(...is it possible to replace it by something else? I dont think
        >simulating it will be feasible....[/color]

        Here's one I prepared earlier:

        if sys.version_inf o < (2,3):
        def enumerate(l):
        return zip(range(len(l )), l)

        which will suck somewhat on large lists compared to being able to
        do it with iterators.

        --
        \S -- siona@chiark.gr eenend.org.uk -- http://www.chaos.org.uk/~sion/
        ___ | "Frankly I have no feelings towards penguins one way or the other"
        \X/ | -- Arthur C. Clarke
        her nu becomeþ se bera eadward ofdun hlæddre heafdes bæce bump bump bump

        Comment

        • Fuzzyman

          #5
          Re: Problem with the sort() function


          Sion Arrowsmith wrote:[color=blue]
          > clementine <kashmira_v_pha lak@yahoo.com> wrote:[color=green]
          > >Thanx Nick...I forgot to mention im using python 2.2 and along with[/color][/color]
          a host[color=blue][color=green]
          > >of other things it doesnt seem to have the enumarate built in[/color][/color]
          function[color=blue][color=green]
          > >:(:(:(...is it possible to replace it by something else? I dont[/color][/color]
          think[color=blue][color=green]
          > >simulating it will be feasible....[/color]
          >
          > Here's one I prepared earlier:
          >
          > if sys.version_inf o < (2,3):
          > def enumerate(l):
          > return zip(range(len(l )), l)
          >
          > which will suck somewhat on large lists compared to being able to
          > do it with iterators.
          >[/color]

          Iterators are available in python 2.2
          class enumerate:
          def __init__(self, inlist):
          self.inlist = inlist
          self.index = 0

          def next(self):
          if self.index >= len(self.inlist ): raise StopIteration
          thisone = self.inlist[self.index]
          self.index += 1
          return self.index-1, thisone

          def __iter__(self):
          return self

          Regards,

          Fuzzy
          http://www.voidspace.org.uk/python/index.shtml
          [color=blue]
          > --
          > \S -- siona@chiark.gr eenend.org.uk -- http://www.chaos.org.uk/~sion/
          > ___ | "Frankly I have no feelings towards penguins one way or the[/color]
          other"[color=blue]
          > \X/ | -- Arthur C. Clarke
          > her nu becomeþ se bera eadward ofdun hlæddre heafdes bæce bump[/color]
          bump bump

          Comment

          • Scott David Daniels

            #6
            Re: Problem with the sort() function

            Nick Coghlan wrote:[color=blue]
            >
            > def mysort(iterable , cmp=None, key=None, reverse=False):
            > "return a sorted copy of its input"
            > if sys.version_inf o >= (2,4):
            > return sorted(iterable , cmp, key, reverse)
            > seq = list(iterable)
            > if reverse:
            > seq.reverse() # preserve stability
            > if key is not None:
            > seq = [(key(elem), i, elem) for i, elem in enumerate(seq)]
            > seq.sort(cmp)
            > if key is not None:
            > seq = [elem for (key, i, elem) in seq]
            > if reverse:
            > seq.reverse()
            > return seq
            >[/color]

            You'd be better off defining things once (and using the standard name)
            rather than doing a test every time your function is called.
            Something like:

            import sys
            ...
            if sys.version_inf o < (2, 3):
            def enumerate(itera ble): # iterators not yet invented
            return zip(range(len(i terable)), iterable)

            if sys.version_inf o < (2, 4):
            def sorted(iterable , cmp=None, key=None, reverse=False):
            "return a sorted copy of its input"
            seq = list(iterable)
            if reverse:
            seq.reverse() # preserve stability
            if key is not None:
            seq = [(key(elem), i, elem) for i, elem
            in enumerate(seq)]
            seq.sort(cmp)
            if key is not None:
            seq = [elem for (key, i, elem) in seq]
            if reverse:
            seq.reverse()
            return seq

            If you like your names better, you can use:

            if sys.version_inf o >= (2, 4):
            mysort = sorted
            else:
            def mysort(iterable , cmp=None, key=None, reverse=False):
            ...

            or even (if you can't be bothered to look up when features happened):

            try:
            test = enumerate
            except NameError:
            def enumerate(itera ble):
            ...
            try:
            test = sorted
            except NameError:
            def sorted(iterable , cmp=None, key=None, reverse=False):
            ...


            --Scott David Daniels
            Scott.Daniels@A cm.Org

            Comment

            • Duncan Booth

              #7
              Re: Problem with the sort() function

              Scott David Daniels wrote:
              [color=blue]
              > if sys.version_inf o < (2, 4):
              > def sorted(iterable , cmp=None, key=None, reverse=False):
              > "return a sorted copy of its input"
              > seq = list(iterable)
              > if reverse:
              > seq.reverse() # preserve stability
              > if key is not None:
              > seq = [(key(elem), i, elem) for i, elem
              > in enumerate(seq)]
              > seq.sort(cmp)
              > if key is not None:
              > seq = [elem for (key, i, elem) in seq]
              > if reverse:
              > seq.reverse()
              > return seq[/color]

              I think you may have some unintended indentation on the 'seq.sort' line
              otherwise this only sorts when a key is specified.

              Also, you probably want:

              if key is not None:
              if reverse:
              seq = [(key(elem), -i, elem) for i, elem
              in enumerate(seq)]
              else:
              seq = [(key(elem), i, elem) for i, elem
              in enumerate(seq)]

              to handle the case where both key and reverse are given.

              Comment

              • Steven Bethard

                #8
                Re: Problem with the sort() function

                Fuzzyman wrote:[color=blue]
                > Iterators are available in python 2.2
                > class enumerate:
                > def __init__(self, inlist):
                > self.inlist = inlist
                > self.index = 0
                >
                > def next(self):
                > if self.index >= len(self.inlist ): raise StopIteration
                > thisone = self.inlist[self.index]
                > self.index += 1
                > return self.index-1, thisone
                >
                > def __iter__(self):
                > return self[/color]

                A simpler version that works with any iterable (not just sequences):

                py> class enumerate(objec t):
                .... def __init__(self, iterable):
                .... self._next = iter(iterable). next
                .... self._index = -1
                .... def __iter__(self):
                .... return self
                .... def next(self):
                .... self._index += 1
                .... return self._index, self._next()
                ....
                py> enumerate('abcd e')
                <__main__.enume rate object at 0x011627F0>
                py> list(enumerate( 'abcde'))
                [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd'), (4, 'e')]

                STeVe

                Comment

                • Steven Bethard

                  #9
                  Re: Problem with the sort() function

                  Scott David Daniels wrote:[color=blue]
                  > or even (if you can't be bothered to look up when features happened):
                  >
                  > try:
                  > test = enumerate
                  > except NameError:
                  > def enumerate(itera ble):
                  > ...
                  > try:
                  > test = sorted
                  > except NameError:
                  > def sorted(iterable , cmp=None, key=None, reverse=False):
                  > ...[/color]

                  Ridiculously minor nit, but there's no reason to assign to test:

                  try:
                  enumerate
                  except NameError:
                  def enumerate(itera ble):
                  ...
                  try:
                  sorted
                  except NameError:
                  def sorted(iterable , cmp=None, key=None, reverse=False):
                  ...

                  Just evaluating the expression 'enumerate' or 'sorted' should raise the
                  NameError if they don't exist.

                  STeVe

                  Comment

                  • John Machin

                    #10
                    Re: Problem with the sort() function


                    clementine wrote:[color=blue]
                    > Thanx Nick...I forgot to mention im using python 2.2 and along with a[/color]
                    host[color=blue]
                    > of other things it doesnt seem to have the enumarate built in[/color]
                    function[color=blue]
                    > :(:(:(...is it possible to replace it by something else? I dont think
                    > simulating it will be feasible....[/color]

                    Faced with Nick's one line of code that uses 'enumerate', you have the
                    choice of building (and testing) an elaborate time machine to make a
                    SLOW 'enumerate' available for 2.2, or you can just patch Nick's
                    sorting gadget in a very straightforward manner:

                    modern as per Nick:
                    seq = [(key(elem), i, elem) for i, elem in enumerate(seq)]

                    ancient:
                    seq = [(key(seq[i]), i, seq[i]) for i in xrange(len(seq) )]

                    Comment

                    • clementine

                      #11
                      Re: Problem with the sort() function

                      Thanks everyone!!:-) Nicks solution coupled with John's modifications
                      worked great for 2.2!! Yipeee...!!:):)


                      Comment

                      Working...