{"id":783,"date":"2018-06-11T23:53:35","date_gmt":"2018-06-11T23:53:35","guid":{"rendered":"http:\/\/www.afternerd.com\/blog\/?p=783"},"modified":"2019-01-13T03:12:28","modified_gmt":"2019-01-13T03:12:28","slug":"python-sort-list","status":"publish","type":"post","link":"https:\/\/www.afternerd.com\/blog\/python-sort-list\/","title":{"rendered":"Python: How to Sort a List? (The Right Way)"},"content":{"rendered":"<p>It happens all the time.<\/p>\n<p>You have a python list and you want to sort the items it contains.<\/p>\n<p>Basically, you can either use <span class=\"symbol\">sort<\/span> or <span class=\"symbol\">sorted<\/span> to achieve what you want.<\/p>\n<p>The difference between <strong>sort<\/strong> and <strong>sorted<\/strong> is that <strong>sort<\/strong> is a list method that modifies the list in place whereas <strong>sorted<\/strong> is a built-in function that creates a new list without touching the original one.<\/p>\n<p>In this article, I will teach you how to use these functions to sort, in an ascending or descending manner, a list of numbers, strings, tuples, or literally any object.<\/p>\n<p>I will also teach you how to define your own custom sort functions.<\/p>\n<p>Read the whole article if you want to learn all about list sorting in Python. Otherwise, feel free to jump straight to a specific section.<\/p>\n<ul>\n<li><a href=\"#sort-numbers\">Sorting a list of numbers<\/a><\/li>\n<li><a href=\"#sort-strings\">Sorting a list of strings<\/a>\n<ul>\n<li><a href=\"#sort-strings-case-insensitive\">Sorting a list of strings in a case insensitive manner<\/a><\/li>\n<\/ul>\n<\/li>\n<li><a href=\"#sort-tuples\">Sorting a list of tuples<\/a>\n<ul>\n<li><a href=\"#sort-tuples-second-element\">Sorting a list of tuples by the second element<\/a><\/li>\n<\/ul>\n<\/li>\n<li><a href=\"#sort-objects\">Sorting a list of objects<\/a><\/li>\n<\/ul>\n<h2 id=\"sort-numbers\">Sorting a List of Numbers<\/h2>\n<p>Sorting a numerical list is a piece of cake in Python.<\/p>\n<p>You can sort a list of numbers (integers or floats) very easily by using the <span class=\"symbol\">sort<\/span> method.<\/p>\n<p>Here is an example:<\/p>\n<pre class=\"prettyprint\"><code>&gt;&gt;&gt; L = [15, 22.4, 8, 10, 3.14]\r\n&gt;&gt;&gt; L.sort()\r\n&gt;&gt;&gt; L\r\n[3.14, 8, 10, 15, 22.4]<\/code><\/pre>\n<p>Notice that the list <strong>L<\/strong> was sorted in place. No new objects were created.<\/p>\n<p>If you want to create a new sorted list without modifying the original one, you should use the <span class=\"symbol\">sorted<\/span> function instead.<\/p>\n<pre class=\"prettyprint\"><code>&gt;&gt;&gt; L = [15, 22.4, 8, 10, 3.14]\r\n&gt;&gt;&gt; sorted_list = sorted(L)\r\n&gt;&gt;&gt; L\r\n[15, 22.4, 8, 10, 3.14]\r\n&gt;&gt;&gt; sorted_list\r\n[3.14, 8, 10, 15, 22.4]<\/code><\/pre>\n<p>As you can notice, both <strong>sort<\/strong> and <strong>sorted<\/strong> sort items in an ascending order by default.<\/p>\n<p>If you want to sort in a descending order, all you have to do is add the parameter <span class=\"symbol\">reverse = True<\/span> to either the <strong>sort<\/strong> or <strong>sorted<\/strong> functions.<\/p>\n<p>They both accept it!<\/p>\n<p>Here is another example to show how you can use the <strong>sort<\/strong> method in a descending manner.<\/p>\n<pre class=\"prettyprint\"><code>&gt;&gt;&gt; L = [15, 22.4, 8, 10, 3.14]\r\n&gt;&gt;&gt; L.sort(reverse = True)\r\n&gt;&gt;&gt; L\r\n[22.4, 15, 10, 8, 3.14]<\/code><\/pre>\n<p>Now let&#8217;s take a look at how to sort a list of strings.<\/p>\n<h2 id=\"sort-strings\">Sorting a List of Strings<\/h2>\n<p>So what if you want to sort a list of strings instead of numbers?<\/p>\n<p>Well, nothing really changes.<\/p>\n<p>You can still use <strong>sort<\/strong> or <strong>sorted<\/strong>.<\/p>\n<p>Here is an example using <strong>sort<\/strong>:<\/p>\n<pre class=\"prettyprint\"><code>&gt;&gt;&gt; L = [\"oranges\", \"apples\", \"bananas\"]\r\n&gt;&gt;&gt; L.sort()\r\n&gt;&gt;&gt; L\r\n['apples', 'bananas', 'oranges']<\/code><\/pre>\n<p>and you can still use the <strong>reverse<\/strong> parameter to sort in a descending order.<\/p>\n<p>Let&#8217;s look at another example, this time using\u00a0<strong>sorted<\/strong><\/p>\n<pre class=\"prettyprint\"><code>&gt;&gt;&gt; L = [\"oranges\", \"apples\", \"bananas\"]\r\n&gt;&gt;&gt; sorted(L, reverse = True)\r\n['oranges', 'bananas', 'apples']<\/code><\/pre>\n<p>So far so good, but there is a catch.<\/p>\n<p>Let&#8217;s see what happens when there exists uppercase letters.<\/p>\n<pre class=\"prettyprint\"><code>&gt;&gt;&gt; L = [\"oranges\", \"apples\", \"Bananas\"]\r\n&gt;&gt;&gt; L.sort()\r\n&gt;&gt;&gt; L\r\n['Bananas', 'apples', 'oranges']<\/code><\/pre>\n<p>That&#8217;s interesting. <span class=\"symbol\">Bananas<\/span> appears before <span class=\"symbol\">apples<\/span><\/p>\n<p>The reason for that is because Python treats all uppercase letters to be lower than lowercase letters.<\/p>\n<p>If that&#8217;s what you want then cool, go ahead and use it without any modifications.<\/p>\n<p>However, most of the time you want to treat strings as <em>case insensitive<\/em> when it comes to sorting.<\/p>\n<h3 id=\"sort-strings-case-insensitive\">So how can you sort a list of strings in a case insensitive manner?<\/h3>\n<p>Starting with Python 2.4, both <strong>sort<\/strong> and <strong>sorted<\/strong> added an optional <span class=\"symbol\">key<\/span> parameter.<\/p>\n<p>This <span class=\"symbol\">key<\/span> parameter specifies a function that will be called on each list item before making comparisons.<\/p>\n<p>This is indeed very helpful because now we can pass the <span class=\"symbol\">str.lower<\/span> as the <strong>key<\/strong> parameter to the <strong>sort<\/strong> function.<\/p>\n<p>And this will instruct the <strong>sort<\/strong> function to perform comparisons between the all-lowercase versions of the strings which is exactly what we want!<\/p>\n<pre class=\"prettyprint\"><code>&gt;&gt;&gt; L = [\"oranges\", \"apples\", \"Bananas\"]\r\n&gt;&gt;&gt; L.sort(key=str.lower)\r\n&gt;&gt;&gt; L\r\n['apples', 'Bananas', 'oranges']<\/code><\/pre>\n<p>As you can see, now the sorting is case insensitive.<\/p>\n<p>In fact the <strong>key<\/strong> parameter is very powerful as it allows us to define our own custom sorting functions as we will see later.<\/p>\n<h2 id=\"sort-tuples\">Sorting a List of Tuples<\/h2>\n<p>Before we dive in, let&#8217;s see how Python compares two tuples.<\/p>\n<p>Tuples are compared element by element starting from the first element which is very similar to how strings are compared.<\/p>\n<p>In other words, you start out by comparing the first elements of the tuples and if they are not equal, this is the result of the comparison.<\/p>\n<p>If they are equal, the second items are compared and so on.<\/p>\n<pre class=\"prettyprint\"><code>&gt;&gt;&gt; (2, 4) &lt; (4, 1) \r\nTrue \r\n&gt;&gt;&gt; (2, 4) &lt; (2, 6)\r\nTrue<\/code><\/pre>\n<p>If this is your goal, then just use the <span class=\"symbol\">sort<\/span> method or the <span class=\"symbol\">sorted<\/span> function and both will work just fine.<\/p>\n<pre class=\"prettyprint\"><code>&gt;&gt;&gt; sorted([(5, 4), (3, 3), (3, 10)])\r\n[(3, 3), (3, 10), (5, 4)]<\/code><\/pre>\n<p>But sometimes this is not really what you want.<\/p>\n<p>For example, assume you have a list of tuples where the first element in each tuple represents a name, and the second one represents the age.<\/p>\n<p>And we want to sort this list of tuples by age.<\/p>\n<h3 id=\"sort-tuples-second-element\">how can you sort a list of tuples by the second element?<\/h3>\n<p>The key parameter will again come to the rescue.<\/p>\n<p>We can define our custom sort by defining our own key function.<\/p>\n<pre class=\"prettyprint\"><code>def custom_sort(t):\r\n    return t[1]\r\n\r\nL = [(\"Alice\", 25), (\"Bob\", 20), (\"Alex\", 5)]\r\nL.sort(key=custom_sort)\r\nprint(L)\r\n\r\n# output\r\n# [('Alex', 5), ('Bob', 20), ('Alice', 25)]<\/code><\/pre>\n<p>There you go!<\/p>\n<p>You can even write a neater code if you want by using <a href=\"https:\/\/www.programiz.com\/python-programming\/anonymous-function\" target=\"_blank\" rel=\"noopener\">lambdas<\/a>.<\/p>\n<pre class=\"prettyprint\"><code>L = [(\"Alice\", 25), (\"Bob\", 20), (\"Alex\", 5)]\r\nL.sort(key=lambda x: x[1])\r\nprint(L)\r\n# output\r\n# [('Alex', 5), ('Bob', 20), ('Alice', 25)]<\/code><\/pre>\n<h2 id=\"sort-objects\">Sorting a List of Objects<\/h2>\n<p>So what about if you have a list of generic objects and you want to sort these objects based on some custom criteria.<\/p>\n<p>The\u00a0<span class=\"symbol\">key<\/span> parameter is your friend.<\/p>\n<p>Let&#8217;s take an example.<\/p>\n<p>Assume you have a <span class=\"symbol\">User<\/span> class that looks like this<\/p>\n<pre class=\"prettyprint\"><code>class User:\r\n    def __init__(self, name, age):\r\n        self.name = name\r\n        self.age = age<\/code><\/pre>\n<p>A simple class that has name and age attributes.<\/p>\n<p>Let&#8217;s create some <span class=\"symbol\">User<\/span> objects and add them to a list.<\/p>\n<pre class=\"prettyprint\"><code>Bob = User('Bob', 20)\r\nAlice = User('Alice', 30)\r\nLeo = User('Leo', 15)\r\nL = [Bob, Alice, Leo]<\/code><\/pre>\n<p>Now let&#8217;s say you want to sort the objects in this list alphabetically by the <span class=\"symbol\">name<\/span> attribute.<\/p>\n<p>Here is one way you can do that:<\/p>\n<pre class=\"prettyprint\"><code>L.sort(key=lambda x: x.name)\r\nprint([item.name for item in L])\r\n# output: ['Alice', 'Bob', 'Leo']<\/code><\/pre>\n<p>If you want to sort the objects based on the <span class=\"symbol\">age<\/span> attribute instead, here is what you need to do:<\/p>\n<pre class=\"prettyprint\"><code>L.sort(key=lambda x: x.age)\r\nprint([item.name for item in L])\r\n# output: ['Leo', 'Bob', 'Alice']<\/code><\/pre>\n<p>And just like that, you can define any custom sort on any python object you can think of.<\/p>\n<p>Happy sorting! \ud83d\ude42<\/p>\n<h3>Learning Python?<\/h3>\n<p>Check out <a href=\"https:\/\/courses.afternerd.com\/\">the Courses section!<\/a><\/p>\n\n<h2>Featured Posts<\/h2>\n<ul>\n<li><a href=\"https:\/\/www.afternerd.com\/blog\/learn-python\/\">The Python Learning Path (From Beginner to Mastery)<\/a><\/li>\n<li><a href=\"https:\/\/www.afternerd.com\/blog\/learn-computer-science\/\">Learn Computer Science (From Zero to Hero)<\/a><\/li>\n<li><a href=\"https:\/\/www.afternerd.com\/blog\/coding-interview\/\">Coding Interview Preparation Guide<\/a><\/li>\n<li><a href=\"https:\/\/www.afternerd.com\/blog\/stock-investing-for-beginners\/\">The Programmer&#8217;s Guide to Stock Market Investing<\/a><\/li>\n<li><a href=\"https:\/\/www.afternerd.com\/blog\/start-programming-blog\/\">How to Start Your Programming Blog?<\/a><\/li>\n<\/ul>\n<div class=\"after-post-box\">\n<h2>Are you Beginning your Programming Career?<\/h2>\n<h3>I provide my best content for beginners in the newsletter.<\/h3>\n<ul>\n<li>Python tips for beginners, intermediate, and advanced levels.<\/li>\n<li>CS Career tips and advice.<\/li>\n<li>Special discounts on my premium courses when they launch.<\/li>\n<\/ul>\n<p>And so much more&#8230;<\/p>\n<h3>Subscribe now. It&#8217;s Free.<\/h3>\n<p><script type=\"text\/javascript\" src=\"\/\/mautic.afternerd.com\/form\/generate.js?id=2\"><\/script><\/p>\n<\/div>\n\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":796,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12],"tags":[13],"yst_prominent_words":[587,581,560,572,586,558,580,582,574,598,567,590,562,563,569,592,597,594,593,596],"_links":{"self":[{"href":"https:\/\/www.afternerd.com\/blog\/wp-json\/wp\/v2\/posts\/783"}],"collection":[{"href":"https:\/\/www.afternerd.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.afternerd.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.afternerd.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.afternerd.com\/blog\/wp-json\/wp\/v2\/comments?post=783"}],"version-history":[{"count":17,"href":"https:\/\/www.afternerd.com\/blog\/wp-json\/wp\/v2\/posts\/783\/revisions"}],"predecessor-version":[{"id":1259,"href":"https:\/\/www.afternerd.com\/blog\/wp-json\/wp\/v2\/posts\/783\/revisions\/1259"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.afternerd.com\/blog\/wp-json\/wp\/v2\/media\/796"}],"wp:attachment":[{"href":"https:\/\/www.afternerd.com\/blog\/wp-json\/wp\/v2\/media?parent=783"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.afternerd.com\/blog\/wp-json\/wp\/v2\/categories?post=783"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.afternerd.com\/blog\/wp-json\/wp\/v2\/tags?post=783"},{"taxonomy":"yst_prominent_words","embeddable":true,"href":"https:\/\/www.afternerd.com\/blog\/wp-json\/wp\/v2\/yst_prominent_words?post=783"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}