ztlevi
5/15/2017 - 6:00 PM

Sort

sorted use function, anonymous function, attrgetter, itemgetter. Does not override the original list!!!

Sort from small to big always use 'a - b', from big to small use 'b-a'.

=========================== Python 2 =========================
In Py2.x, sort allowed an optional function which can be called for doing the comparisons. That function should take two arguments to be compared and then return a negative value for less-than, return zero if they are equal, or return a positive value for greater-than. For example, we can do:

>>>
>>> def numeric_compare(x, y):
...     return x - y
>>> sorted([5, 2, 4, 1, 3], cmp=numeric_compare) 
[1, 2, 3, 4, 5]
Or you can reverse the order of comparison with:

>>>
>>> def reverse_numeric(x, y):
...     return y - x
>>> sorted([5, 2, 4, 1, 3], cmp=reverse_numeric) 
[5, 4, 3, 2, 1]

=========================== Python 3 =========================
When porting code from Python 2.x to 3.x, the situation can arise when you have the user supplying a comparison function and you need to convert that to a key function. The following wrapper makes that easy to do:

def cmp_to_key(mycmp):
    'Convert a cmp= function into a key= function'
    class K:
        def __init__(self, obj, *args):
            self.obj = obj
        def __lt__(self, other):
            return mycmp(self.obj, other.obj) < 0
        def __gt__(self, other):
            return mycmp(self.obj, other.obj) > 0
        def __eq__(self, other):
            return mycmp(self.obj, other.obj) == 0
        def __le__(self, other):
            return mycmp(self.obj, other.obj) <= 0
        def __ge__(self, other):
            return mycmp(self.obj, other.obj) >= 0
        def __ne__(self, other):
            return mycmp(self.obj, other.obj) != 0
    return K
To convert to a key function, just wrap the old comparison function:

>>>
>>> sorted([5, 2, 4, 1, 3], key=cmp_to_key(reverse_numeric))
[5, 4, 3, 2, 1]
In Python 3.2, the functools.cmp_to_key() function was added to the functools module in the standard library.
# Definition for an interval.
# class Interval(object):
#     def __init__(self, s=0, e=0):
#         self.start = s
#         self.end = e

# use anonymous function lambda
sorted(intervals, key = lambda i: i.start)
>>> s
'fasfefdsf'
>>> sorted(s)
['a', 'd', 'e', 'f', 'f', 'f', 'f', 's', 's']

# string cannot use s.sort(), only sorted()
from operator import attrgetter, itemgetter

getName = attrgetter('name')
getName(jack)
#  'jack'

sorted(people, key = attrgetter('name'))
#  [<name: Adam, age: 43>, <name: Becky, age: 11>, <name: Jack, age: 19>]

sorted(people, key = attrgetter('age'))
#  [<name: Becky, age: 11>, <name: Jack, age: 19>, <name: Adam, age: 43>]

sorted(subjects, itemgetter(0), reverse=True)
def byAge_key(person):
  return person.age
sorted(people, key = byAge_key)
#  [<name: Becky, age: 11>, <name: Jack, age: 19>, <name: Adam, age: 43>]

# reverse
sorted(student_tuples, key=itemgetter(2), reverse=True)