Pythonsort and sorted advanced sorting skills

Source: Internet
Author: User
Tags python list
This article mainly introduces pythonsort and sorted advanced sorting skills. This article describes basic sorting, ascending and descending sorting, sorting stability and complex sorting, cmp function sorting, and so on, you can refer to the Python list built-in sort () method for sorting. you can also use the python built-in global sorted () method to generate a new sequence for sorting the iterated sequence.

1) sorting basics

Simple ascending sorting is very easy. You only need to call the sorted () method. It returns a new list. the elements of the new list are sorted based on the smaller operator (_ lt.

The code is as follows:


>>> Sorted ([5, 2, 3, 1, 4])
[1, 2, 3, 4, 5]



You can also use the list. sort () method to sort data. in this case, the list itself will be modified. This method is generally not as convenient as sorted (), but it is more effective if you do not need to keep the original list.

The code is as follows:


>>> A = [5, 2, 3, 1, 4]
>>> A. sort ()
>>>
[1, 2, 3, 4, 5]


The other difference is that the list. sort () method is only defined in the list. On the contrary, the sorted () method is effective for all iteratable sequences.

The code is as follows:

>>>
Sorted ({1: 'D', 2: 'B', 3: 'B', 4: 'e', 5: 'A '})
[1, 2, 3, 4, 5]

2) key parameters/functions

Starting from python2.4, the list. sort () and sorted () functions add the key parameter to specify a function, which will be called before each element comparison. For example, you can use the function specified by the key to ignore the case sensitivity of the string:

The code is as follows:


>>> Sorted ("This is a test string from Andrew". split (), key = str. lower)
['A', 'Andrew ', 'from', 'is', 'string', 'test', 'eas']


The value of the key parameter is a function. this function has only one parameter and returns a value for comparison. This technology is quick because the function specified by the key will call each element accurately.

More widely used is to sort the sequences of complex objects by some values of complex objects, such:

The code is as follows:


>>> 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)]

The same technology applies to complex objects with naming properties, such:

The code is as follows:


>>> 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 ('jar', '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)]

3) Operator module functions

The preceding key parameters are widely used. Therefore, python provides some convenient functions to make access methods easier and faster. The operator module has itemgetter and attrgetter. the methodcaller method has been added since 2.6. Using these methods, the above operations will become more concise and fast:

The code is as follows:


>>> From operator import itemgetter, attrgetter
>>> Sorted (student_tuples, key = itemgetter (2 ))
[('Dave ',' B ', 10), ('Jane', 'B', 12), ('John', 'A', 15)]
>>> Sorted (student_objects, key = attrgetter ('age '))
[('Dave ',' B ', 10), ('Jane', 'B', 12), ('John', 'A', 15)]


The operator module also allows multi-level sorting, for example, first by grade and then by age:

The code is as follows:


>>> Sorted (student_tuples, key = itemgetter (1, 2 ))
[('John', 'A', 15), ('Dave ',' B ', 10), ('Jane', 'B', 12)]
>>> Sorted (student_objects, key = attrgetter ('grad', 'age '))
[('John', 'A', 15), ('Dave ',' B ', 10), ('Jane', 'B', 12)]

4) ascending and descending

Both list. sort () and sorted () accept a reverse (True or False) parameter to indicate ascending or descending sorting. For example, the student sort in descending order is as follows:

The code is as follows:


>>> Sorted (student_tuples, key = itemgetter (2), reverse = True)
[('John', 'A', 15), ('Jane ',' B ', 12), ('Dave', 'B', 10)]
>>> Sorted (student_objects, key = attrgetter ('age'), reverse = True)
[('John', 'A', 15), ('Jane ',' B ', 12), ('Dave', 'B', 10)]

5) stable and complex sorting

From python2.2, the sorting is ensured to be stable. It means that if multiple elements have the same key, their order remains unchanged before and after sorting.

The code is as follows:


>>> Data = [('red', 1), ('blue', 1), ('red', 2), ('blue', 2)]
>>> Sorted (data, key = itemgetter (0 ))
[('Blue', 1), ('blue', 2), ('red', 1), ('red', 2)]


Note that the order of 'blue' after sorting is maintained, that is, 'Blue ', 1 is in front of 'Blue', 2.

More complex, you can build multiple steps to perform more complex sorting. for example, student data is first sorted in descending order of grade, and then in ascending order of age.

The code is as follows:


>>> S = sorted (student_objects, key = attrgetter ('age') # sort on secondary key
>>> Sorted (s, key = attrgetter ('grade '), reverse = True) # now sort on primary key, descending
[('Dave ',' B ', 10), ('Jane', 'B', 12), ('John', 'A', 15)]

6) The oldest sorting method-DSU

We call it DSU (Decorate-Sort-Undecorate). The reason is that the sorting process requires the following three steps:
First, the original list is decorated so that the values of the new list can be used to control the sorting;
Second, sort the list after decoration;
Third, delete the decoration and re-construct the sorted decoration list to the original list type;

For example, sort student data by grade using the DSU method:
>>> Decorated = [(student. grade, I, student) for I, student in enumerate (student_objects)]
>>> Decorated. sort ()
>>> [Student for grade, I, student in decorated] # undecorate
[('John', 'A', 15), ('Jane ',' B ', 12), ('Dave', 'B', 10)]
The comparison above works because tuples can be used for comparison. the comparison between tuples first compares the first element of tuples. if the first element is the same, then the second element is compared, and so on.

Not all of the above tuples need to contain indexes, but including indexes can have the following benefits:
First, the sorting is stable. if the two elements have the same key, their original order remains unchanged;
Second, the original elements do not need to be used for comparison, because it is sufficient for the first and second elements of tuples to be used for comparison.

This method has been widely used by RandalL. in perl, another name is also known as Schwartzian transform.

If the calculation of large list or list elements is too complex, DSU may be the fastest sorting method before python2.4. However, after 2.4, the key function described above provides similar functions.

7) sorting methods commonly used in other languages-cmp functions

Prior to python2.4, the sorted () and list. sort () functions did not provide the key parameter, but the cmp parameter was provided to allow you to specify a comparison function. This method is also common in other languages.

In python3.0, the cmp parameter is completely removed, which simplifies and unifies the language and reduces conflicts between the high-level comparison and the _ cmp _ method.

In python2.x, the cmp parameter specifies a function for comparing elements. This function requires two parameters, and then returns a negative number indicating less than, 0 indicating equal to, and positive representing greater. For example:

The code is as follows:


>>> 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 sort them in reverse order:

The code is as follows:


>>> Def reverse_numeric (x, y ):
Return y-x
>>> Sorted ([5, 2, 4, 1, 3], cmp = reverse_numeric)
[5, 4, 3, 2, 1]


When we Port the existing 2.x code to 3.x, we need to convert the cmp function to the key function. the following wrapper is very helpful:

The code is as follows:


Def cmp_to_key (mycmp ):
'Convert a cmp = function into a key = function'
Class K (object ):
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 cmp to a key, you only need:

The code is as follows:


>>> Sorted ([5, 2, 4, 1, 3], key = cmp_to_key (reverse_numeric ))
[5, 4, 3, 2, 1]


From python2.7, the cmp_to_key () function is added to the functools module.

8) Other considerations

* You can use locale. strxfrm () as the key function or local. strcoll () as the cmp function to sort regions.

* The reverse parameter retains the stability of sorting. if it is interesting, you can use the reversed () function twice to achieve the same effect:

The code is as follows:


>>> Data = [('red', 1), ('blue', 1), ('red', 2), ('blue', 2)]
>>> Assert sorted (data, reverse = True) = list (reversed (sorted (reversed (data ))))

* In fact, sorting is performed by calling the _ cmp _ element internally, so we can add the _ cmp _ method for the element type to make the elements comparable. for example:

The code is as follows:


>>> Student. _ lt _ = lambda self, other: self. age <other. age
>>> Sorted (student_objects)
[('Dave ',' B ', 10), ('Jane', 'B', 12), ('John', 'A', 15)]


* The key function can not only access the internal data of elements to be sorted, but also access external resources. for example, if a student's score is stored in a dictionary, you can use this dictionary to sort the list of student names, as follows:

The code is as follows:


>>> Students = ['Dave ', 'John', 'Jane']
>>> Newgrades = {'John': 'F', 'jar': 'A', 'Dave ': 'C '}
>>> Sorted (students, key = newgrades. _ getitem __)
['Jane ', 'Dave', 'John']

* If you need to sort data while processing data, sort (), sorted () or bisect. insort () is not the best method. In this case, you can use heap, red-black tree, or treap.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.