FROM:https://www.pythoncentral.io/how-to-sort-python-dictionaries-by-key-or-value/
AND https://www.pythoncentral.io/how-to-sort-a-list-tuple-or-object-with-sorted-in-python/
The dict
(dictionary) class object in Python is a very versatile and useful container type, able to store a collection of values and retrieve them via keys.
numbers = {'first': 1, 'second': 2, 'third': 3, 'Fourth': 4}
>>> sorted(numbers)
['Fourth', 'first', 'second', 'third']
>>> sorted(numbers.values())
[1, 2, 3, 4]
>>> sorted(numbers, key=numbers.__getitem__)
# In order of sorted values: [1, 2, 3, 4]
['first', 'second', 'third', 'Fourth']
# Uses the first element of each tuple to compare
>>> [value for (key, value) in sorted(numbers.items())]
[4, 1, 2, 3]
# In order of sorted keys: ['Fourth', 'first', 'second', 'third']
>>> sorted(numbers, key=numbers.__getitem__, reverse=True)
['Fourth', 'third', 'second', 'first']
>>> [value for (key, value) in sorted(numbers.items(), reverse=True)]
[3, 2, 1, 4]
reverse 标识若为true,顺序为反向排序
# Won't change the items to be returned, only while sorting
>>> sorted(numbers, key=str.lower)
['first', 'Fourth', 'second', 'third']
>>> month = dict(one='January',
two='February',
three='March',
four='April',
five='May')
>>> numbermap = {'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5}
>>> sorted(month, key=numbermap.__getitem__)
['one', 'two', 'three', 'four', 'five']
同时我们可以对一些字典进行利用一些赋值的数据进行权值排序
# Assuming the keys in both dictionaries are EXACTLY the same:
>>> [month[i] for i in sorted(month, key=numbermap.__getitem__)]
['January', 'February', 'March', 'April', 'May']
If we wanted to sort our key/value strings by the number of repeated letters in each string, we could define our own custom method to use in the
sorted
key argument:def repeats(string):
# Lower the case in the string
string = string.lower()
# Get a set of the unique letters
uniques = set(string)
# Count the max occurrences of each unique letter
counts = [string.count(letter) for letter in uniques]
return max(counts)
# From greatest to least repeats
>>> sorted(month.values(), key=repeats, reverse=True)
['February', 'January', 'March', 'April', 'May']
More advanced sorting functionality
def evens1st(num):
# Test with modulus (%) two
if num == 0:
return -2
# It's an even number, return the value
elif num % 2 == 0:
return num
# It's odd, return the negated inverse
else:
return -1 * (num ** -1)
# Max class size first
>>> sorted(trans.values(), key=evens1st, reverse=True)
[30, 24, 33, 7, 0]
Sorting a List(or Tuple) of Custom Python Objects
class Custom(object):
def __init__(self, name, number):
self.name = name
self.number = number
def __repr__(self):
return '{}: {} {}'.format(self.__class__.__name__,
self.name,
self.number)
def getKey(custom):
return custom.number
>>> sorted(customlist, key=getKey)
[Custom: michael 1, Custom: life 42,
Custom: theodore the great 59, Custom: object 99]
Or maybe you feel it's nit-picking,and don't want to type the key keyword everytime,
Redifine our project one more time like this
class Custom(object):
def __init__(self, name, number):
self.name = name
self.number = number
def __repr__(self):
return '{}: {} {}'.format(self.__class__.__name__,
self.name,
self.number)
def __cmp__(self, other):
if hasattr(other, 'number'):
return self.number.__cmp__(other.number)
>>> sorted(customlist)
[Custom: michael 1, Custom: life 42, Custom: theodore the great 59, Custom: object 99]
Sorting a Heterogeneous List of Custom Python Objects
class AnotherObject(object):
def __init__(self, tag, age, rate):
self.tag = tag
self.age = age
self.rate = rate
def __repr__(self):
return '{}: {} {} {}'.format(self.__class__.__name__,
self.tag,
self.age, self.rate)
def __cmp__(self, other):
if hasattr(other, 'age'):
return self.age.__cmp__(other.age)
customlist = [
Custom('object', 99),
Custom('michael', 1),
Custom('theodore the great', 59),
Custom('life', 42),
AnotherObject('bananas', 37, 2.2),
AnotherObject('pants', 73, 5.6),
AnotherObject('lemur', 44, 9.2)
]
try it,and ...error:
>>> sorted(customlist)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: an integer is required
Why? Because
Custom
doesn't have an attribute called age
and AnotherObject
doesn't have an attribute called number
.Let's redefine those objects again!
class Custom(object):
def __init__(self,name,number):
self.name = name
self.number = number
def __repr__(self):
return '{}: {} {}'.format(self.__class__.__name__,
self.name,
self.number)
def __cmp__(self, other):
if hasattr(other, 'getKey'):
return self.getKey().__cmp__(other.getKey())
def getKey(self):
return self.number
class AnotherObject(object):
def __init__(self, tag, age, rate):
self.tag = tag
self.age = age
self.rate = rate
def __repr__(self):
return '{}: {} {} {}'.format(self.__class__.__name__,
self.tag,
self.age, self.rate)
def __cmp__(self, other):
if hasattr(other, 'getKey'):
return self.getKey().__cmp__(other.getKey())
def getKey(self):
return self.age
>>> sorted(customlist)
[Custom: michael 1, AnotherObject: bananas 37 2.2,
Custom: life 42, AnotherObject: lemur 44 9.2,
Custom: theodore the great 59, AnotherObject: pants 73 5.6,
Custom: object 99]
And it finally Success
You can do that too. If you leave out the
__cmp__
functions in each object, and define an outside function like so:def getKey(customobj):
return customobj.getKey()\
And then call sorted like so:
>>> sorted(customlist, key=getKey)
[Custom: michael 1, AnotherObject: bananas 37 2.2,
Custom: life 42, AnotherObject: lemur 44 9.2,
Custom: theodore the great 59, AnotherObject: pants 73 5.6,
Custom: object 99]