A key can be a function that returns a tuple:
s = sorted(s, key = lambda x: (x[1], x[2]))
Or you can achieve the same using itemgetter
(which is faster and avoids a Python function call):
import operator
s = sorted(s, key = operator.itemgetter(1, 2))
And notice that here you can use sort
instead of using sorted
and then reassigning:
s.sort(key = operator.itemgetter(1, 2))
I'm not sure if this is the most pythonic method ... I had a list of tuples that needed sorting 1st by descending integer values and 2nd alphabetically. This required reversing the integer sort but not the alphabetical sort. Here was my solution: (on the fly in an exam btw, I was not even aware you could 'nest' sorted functions)
a = [('Al', 2), ('Bill', 1), ('Carol', 2), ('Abel', 3), ('Zeke', 2), ('Chris', 1)]
b = sorted(sorted(a, key = lambda x: x[0]), key = lambda x: x[1], reverse = True)
print(b)[('Abel', 3), ('Al', 2), ('Carol', 2), ('Zeke', 2), ('Bill', 1), ('Chris', 1)]
Several years late to the party but I want to both sort on 2 criteria and use reverse=True
. In case someone else wants to know how, you can wrap your criteria (functions) in parenthesis:
s = sorted(my_list, key = lambda i: (criteria_1(i), criteria_2(i)), reverse = True)
So first I defined a helper method
def attr_sort(self, attrs = ['someAttributeString']:
''
'helper to sort by the attributes named by strings of attrs in order'
''
return lambda k: [getattr(k, attr) for attr in attrs]
then to use it
# would defined elsewhere but showing here for consiseness self.SortListA = ['attrA', 'attrB'] self.SortListB = ['attrC', 'attrA'] records = ....#list of my objects to sort records.sort(key = self.attr_sort(attrs = self.SortListA)) # perhaps later nearby or in another function more_records = ....#another list more_records.sort(key = self.attr_sort(attrs = self.SortListB))
I used it to write a rank function, that ranks a list of classes where each object is in a group and has a score function, but you can add any list of attributes. Note the un-lambda-like, though hackish use of a lambda to call a setter. The rank part won't work for an array of lists, but the sort will.
#First, here 's a pure list version my_sortLambdaLst = [lambda x, y: cmp(x[0], y[0]), lambda x, y: cmp(x[1], y[1])] def multi_attribute_sort(x, y): r = 0 for l in my_sortLambdaLst: r = l(x, y) if r != 0: return r #keep looping till you see a difference return r Lst = [(4, 2.0), (4, 0.01), (4, 0.9), (4, 0.999), (4, 0.2), (1, 2.0), (1, 0.01), (1, 0.9), (1, 0.999), (1, 0.2)] Lst.sort(lambda x, y: multi_attribute_sort(x, y)) #The Lambda of the Lambda for rec in Lst: print str(rec)
Here's a way to rank a list of objects
class probe:
def __init__(self, group, score):
self.group = group
self.score = score
self.rank = -1
def set_rank(self, r):
self.rank = r
def __str__(self):
return '\t'.join([str(self.group), str(self.score), str(self.rank)])
def RankLst(inLst, group_lambda = lambda x: x.group, sortLambdaLst = [lambda x, y: cmp(x.group, y.group), lambda x, y: cmp(x.score, y.score)], SetRank_Lambda = lambda x, rank: x.set_rank(rank)):
#Inner
function is the only way(I could think of ) to pass the sortLambdaLst into a sort
function
def multi_attribute_sort(x, y):
r = 0
for l in sortLambdaLst:
r = l(x, y)
if r != 0: return r #keep looping till you see a difference
return r
inLst.sort(lambda x, y: multi_attribute_sort(x, y))
#Now Rank your probes
rank = 0
last_group = group_lambda(inLst[0])
for i in range(len(inLst)):
rec = inLst[i]
group = group_lambda(rec)
if last_group == group:
rank += 1
else:
rank = 1
last_group = group
SetRank_Lambda(inLst[i], rank) #This is pure evil!!The lambda purists are gnashing their teeth
Lst = [probe(4, 2.0), probe(4, 0.01), probe(4, 0.9), probe(4, 0.999), probe(4, 0.2), probe(1, 2.0), probe(1, 0.01), probe(1, 0.9), probe(1, 0.999), probe(1, 0.2)]
RankLst(Lst, group_lambda = lambda x: x.group, sortLambdaLst = [lambda x, y: cmp(x.group, y.group), lambda x, y: cmp(x.score, y.score)], SetRank_Lambda = lambda x, rank: x.set_rank(rank))
print '\t'.join(['group', 'score', 'rank'])
for r in Lst: print r
convert the list of list into a list of tuples then sort the tuple by multiple fields.
data = [
[12, 'tall', 'blue', 1],
[2, 'short', 'red', 9],
[4, 'tall', 'blue', 13]
]
data = [tuple(x) for x in data]
result = sorted(data, key = lambda x: (x[1], x[2]))
print(result)
output:
[(2, 'short', 'red', 9), (12, 'tall', 'blue', 1), (4, 'tall', 'blue', 13)]
This can be abstracted out into a wrapper function that can take a list and tuples of field and order to sort them on multiple passes.,Both list.sort() and sorted() have a key parameter to specify a function (or other callable) to be called on each list element prior to making comparisons.,The Timsort algorithm used in Python does multiple sorts efficiently because it can take advantage of any ordering already present in a dataset.,Both list.sort() and sorted() accept a reverse parameter with a boolean value. This is used to flag descending sorts. For example, to get the student data in reverse age order:
>>> sorted([5, 2, 3, 1, 4])[1, 2, 3, 4, 5]
>>> a = [5, 2, 3, 1, 4] >>> a.sort() >>> a[1, 2, 3, 4, 5]
>>> sorted({
1: 'D',
2: 'B',
3: 'B',
4: 'E',
5: 'A'
})[1, 2, 3, 4, 5]
>>> sorted("This is a test string from Andrew".split(), key = str.lower)['a', 'Andrew', 'from', 'is', 'string', 'test', 'This']
>>> student_tuples = [ ...('john', 'A', 15), ...('jane', 'B', 12), ...('dave', 'B', 10), ... ] >>> sorted(student_tuples, key = lambda student: student[2]) # sort by age[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
>>> class Student:
...def __init__(self, name, grade, age):
...self.name = name
...self.grade = grade
...self.age = age
...def __repr__(self):
...
return repr((self.name, self.grade, self.age))
>>>
student_objects = [
...Student('john', 'A', 15),
...Student('jane', 'B', 12),
...Student('dave', 'B', 10),
...
] >>>
sorted(student_objects, key = lambda student: student.age) # sort by age[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
Consider a list of tuples. We could get such a list when processing information that was extracted from a spreadsheet program. For example, if we had a spreadsheet with raw census data, we can easily transform it into a sequence of tuples that look like the following.,Once we have each row as a tuple, we can put some []'s around the tuples to make a list. We can then slap an assignment statement around this list of rows and turn our spreadsheet into a Python statement.,We can provide a "key extraction" function to the sort method. This will locate the key value (or a tuple of key values) within the given objects., We can provide a "key extraction" function to the sort method. This will locate the key value (or a tuple of key values) within the given objects.
Consider a list
of
tuple
s. We could get such a
list
when processing information that was
extracted from a spreadsheet program. For example, if we had a
spreadsheet with raw census data, we can easily transform it into a
sequence of tuple
s that look like the
following.
jobData = [
(001, 'Albany', 'NY', 162692),
(003, 'Allegany', 'NY', 11986),
...
(121, 'Wyoming', 'NY', 8722),
(123, 'Yates', 'NY', 5094)
]
Sorting this list
can be done trivially
with the list
sort
method.
jobData.sort()
We must define a function that behaves like the built-in
cmp
function. In our example, we'll define a
comparison which works with the third element of our
jobData
tuple
.
def sort3(a, b):
return cmp(a[2], b[2])
jobData.sort(sort3)
Sorting With Key Extraction. The sort
method of a list can accept a
keyword parameter,
key
, that provides a key
extraction function. This function returns a value which can be used
for comparison purposes. To sort our jobData by the third field, we
can use a function like the following.
def byState(a):
return a[2]
jobData.sort(key = byState)
This byState function returns the selected key value, which is then used by sort to order the tuples in the original list. If we want to sort by a multi-part key, we cna do something like the following.
def byStateJobs(a):
return (a[2], a[3])
How To Multisort List Of Dictionaries In Python,The display of third-party trademarks and trade names on this site does not necessarily indicate any affiliation or endorsement of FaqCode4U.com., 6 days ago In this tutorial, we will learn how to create a list of dictionaries, how to access them, how to append a dictionary to list and how to modify them. Create a List of Dictionaries in Python. In the following program, we create a list of length 3, where all the three elements are of type dict. Python Program , 1 week ago Jul 01, 2022 · Ways to sort list of dictionaries by values in Python – Using itemgetter; Python | Merging two Dictionaries; Python | Combine the values of two dictionaries having same key; Python – Concatenate values with same keys in a list of dictionaries; Python | Sum list of dictionaries with same key; Python | Sum values for each key in nested dictionary
test = [{
"title": title,
"ratio": ratio,
"delta": begin - now()
}]
test = [{
"title": title,
"ratio": ratio,
"delta": begin - now()
}]
sorted(test, key = lambda x: (-d['ratio'], d['delta']))
from operator
import itemgetter >>> result = sorted(test, key = itemgetter('-ratio')) >>> result = sorted(result, key = itemgetter('delta'))