Sorting a List of Lists

Discussion in 'Python' started by apotheos, Jan 30, 2007.

  1. apotheos

    apotheos Guest

    I can't seem to get this nailed down and I thought I'd toss it out
    there as, by gosh, its got to be something simple I'm missing.

    I have two different database tables of events that use different
    schemas. I am using python to collate these records for display. I do
    this by creating a list of lists that look roughly like this:

    events = [['Event URL as String', 'Event Title as String ', Event Date
    as Datetime], ...]

    I then thought I'd just go events.sort(lambda x,y: x[2]<y[2]) and call
    it a day. That didn't work. But then lamda functions like to be very
    simple, maybe object subscripts aren't allowed (even though I didn't
    get an error). So I wrote a comparison function that looks much as you
    would expect:

    def date_compare(list1,
    list2):
    x = list1[2]
    y = list2[2]
    if
    x>y:
    return
    1
    elif
    x==y:
    return
    0
    else: #
    x<y
    return -1

    But as before sorting with this function returns None.

    What have I overlooked?
     
    apotheos, Jan 30, 2007
    #1
    1. Advertisements

  2. All sorts return None. the sort is in place. Check your list post-
    sort.

    THN
     
    Thomas Nelson, Jan 31, 2007
    #2
    1. Advertisements

  3. events = [['Event URL as String', 'Event Title as String ', Event Date
    Comparision functions must return -1, 0 or 1, not a bool.
    You may use a key function instead in this case (requires python 2.4 or
    newer):

    events.sort(key=lambda x: x[2])

    Viktor
     
    =?ISO-8859-1?Q?L=E9tezo?=, Jan 31, 2007
    #3
  4. apotheos

    Larry Bates Guest

    Sort doesn't return a list, it sorts in place. None is
    the result code (if you will) of the sort completion.

    -Larry
     
    Larry Bates, Jan 31, 2007
    #4
  5. apotheos

    Paul Rubin Guest

    Use:
    events.sort(lambda x,y: cmp(x[2], y[2]))
    or:
    events.sort(key=lambda x: x[2])
     
    Paul Rubin, Jan 31, 2007
    #5
  6. a écrit :
    Then you should not use a list of lists, but a list of tuples.
    Lol.

    I guess this is a FAQ. list.sort() performs a destructive in-place sort,
    and always return None. This is in the FineManual:

    [email protected]:~$ python
    Python 2.4.4c1 (#2, Oct 11 2006, 21:51:02)
    [GCC 4.1.2 20060928 (prerelease) (Ubuntu 4.1.1-13ubuntu5)] on linux2
    Type "help", "copyright", "credits" or "license" for more information.Help on method_descriptor:

    sort(...)
    L.sort(cmp=None, key=None, reverse=False) -- stable sort *IN PLACE*;
    cmp(x, y) -> -1, 0, 1

    You may want to use sorted(iterable, cmp=None, key=None, reverse=False)
    if you don't want to sort in-place.

    Also, using comparison functions is usually not the most efficient way
    to do such a sort. In your case, I'd go for a good old
    Decorate/sort/undecorate (AKA schwarzian transform):

    events = [evt for date, evt in
    sorted([(evt[2], evt) for evt in events])]


    HTH
     
    Bruno Desthuilliers, Jan 31, 2007
    #6
  7. apotheos

    Paddy Guest

    I agree with you B., but see the comments here:
    http://www.biais.org/blog/index.php/2007/01/28/23-python-sorting-
    efficiency
    for information on the relative speeds of rolling your own DSU versus
    using itemgetter and key=...

    - Paddy.
     
    Paddy, Jan 31, 2007
    #7
  8. Paddy a écrit :
    Yeps, looks like 2.5 got a real speedup wrt/ itemgetter. Nice to know,
    and thanks for the link (BTW, this profileit() decorator looks pretty
    nice too !-)
     
    Bruno Desthuilliers, Jan 31, 2007
    #8
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.