{"id":128,"date":"2020-09-30T03:30:23","date_gmt":"2020-09-30T03:30:23","guid":{"rendered":"https:\/\/blog.napath.com\/?p=128"},"modified":"2020-09-30T03:36:44","modified_gmt":"2020-09-30T03:36:44","slug":"python-sorted-containers","status":"publish","type":"post","link":"https:\/\/blog.napath.com\/index.php\/2020\/09\/30\/python-sorted-containers\/","title":{"rendered":"Python Sorted Containers"},"content":{"rendered":"\n<p>In this article, I would like to talk about Python Sorted Containers. In python language, the build-in data collection is implemented differently from another language (e.g., C\/C++). That makes python losing some ability or performance to access specific data. For example, in C++ language, std::map and std::set are implemented by a tree structure, that causes the data collections to have an ability to search upper or lower bound (upper_bound, lower_bound) of the selected value. In python, such abilities don&#8217;t exist in the built-in data collection. However, Python has a library to support that ability, which can install additionally. Sorted containers is an open-sourced library that allows us to insert or delete elements very efficiently and the elements maintaining a sorted order. The library contains three containers: SortedList, SortedDict, and SortedSet.<\/p>\n\n\n\n<p>Installation: we can install sorted collection by pip command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$sudo pip install sortedcontainers <\/code><\/pre>\n\n\n\n<p>Python Sorted Container contains three sorted data structure:<\/p>\n\n\n\n<ul><li>SortedList&nbsp;<\/li><li>SortedDict&nbsp;<\/li><li>SortedSet<\/li><\/ul>\n\n\n\n<p>We can use these sorted containers in the same way as build-in python; List\/Dict\/Set. These are some examples of code to use the Sorted containers.<\/p>\n\n\n\n<p><strong>SortedList<\/strong><\/p>\n\n\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\nfrom random import random\nfrom sortedcontainers import SortedList\n\nmainList = SortedList()\nfor i in range(100):\n    mainList.add(random())\n<\/pre>\n\n\n<p><strong>SortedDict<\/strong><\/p>\n\n\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\nfrom sortedcontainers import SortedDict\nfrom random import random\n\nmainList = SortedDict()\n\nfor i in range(100):\n    mainList[i]=(random())\n<\/pre>\n\n\n<p><strong>SortedSet<\/strong><\/p>\n\n\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\nfrom sortedcontainers import SortedSet\nfrom random import random\n\nmainList = SortedSet()\n\nfor i in range(100):\n    mainList.add(random())\n<\/pre>\n\n\n<p>Since the data inside Python Sorted Containers are sorted, the containers can fetch the nearest value (upper bound\/lower bound) like upper_bound, lower_bound in c++ language. In Python Sorted Containers, they are called&nbsp; <strong>bisect_left(<em>value<\/em>)<\/strong>&nbsp;and&nbsp;<strong>bisect_right(<em>value<\/em><\/strong>).&nbsp;<\/p>\n\n\n\n<p><strong>bisect_left(value)<\/strong> &nbsp;return an index to insert&nbsp;<strong>value<\/strong>&nbsp;in the sorted container. if the&nbsp;<strong>value<\/strong>&nbsp;already exists in the container, the function will return the existing value&#8217;s index.<\/p>\n\n\n\n<p><strong>bisect_left(value)<\/strong> return an index to insert&nbsp;<strong>value<\/strong>&nbsp;in the sorted container. if the&nbsp;<strong>value<\/strong>&nbsp;already exists in the container, the function will return the index after the existing value&#8217;s index.<\/p>\n\n\n\n<p>Let&#8217;s see an example.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>>>> sl = SortedList(&#91;10, 12, 14, 16, 18])\n>>> sl.bisect_left(12)\n1\n>>> sl.bisect_left(13)\n2\n>>> sl.bisect_right(13)\n2\n>>> sl.bisect_right(14)\n3<\/code><\/pre>\n\n\n\n<p>As we can see from the example, function bisect_left returns an index of the value, if the value exists in the list; sl.bisect_left(12) return 1 because the index of 12 is the 1st. On the other hand, if the value doesn&#8217;t exist, the function will return the index of an insertion point of the value; sl.bisect_left(13) return 2 because the index 2 is the new position of 13 if there is an insertion. In a similar way to bisect_right, if the value doesn&#8217;t exist, the function will return the index of an insertion position; sl.bisect_right(13) return 2, because it is the insertion position. However, if the value is already in the container, the function will return the index after the existing value; sl.bisect_right(14) returns 3 because 14 is at index 2.<\/p>\n\n\n\n<p>The most advantage of these two functions is the performance. bisect_left and bisect_right can run with O(nlgn) running time, which is optimized for searching application.<\/p>\n\n\n\n<p>reference: <a href=\"http:\/\/www.grantjenks.com\/docs\/sortedcontainers\/\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"http:\/\/www.grantjenks.com\/docs\/sortedcontainers\/\">http:\/\/www.grantjenks.com\/docs\/sortedcontainers\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this article, I would like to talk about Python Sorted Containers. In python language, the build-in data collection is implemented differently from another language (e.g., C\/C++). That makes python losing some ability or performance to access specific data. For example, in C++ language, std::map and std::set are implemented by a tree structure, that causes &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/blog.napath.com\/index.php\/2020\/09\/30\/python-sorted-containers\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Python Sorted Containers&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":149,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[17,9],"tags":[5,4,26,27],"_links":{"self":[{"href":"https:\/\/blog.napath.com\/index.php\/wp-json\/wp\/v2\/posts\/128"}],"collection":[{"href":"https:\/\/blog.napath.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.napath.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.napath.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.napath.com\/index.php\/wp-json\/wp\/v2\/comments?post=128"}],"version-history":[{"count":19,"href":"https:\/\/blog.napath.com\/index.php\/wp-json\/wp\/v2\/posts\/128\/revisions"}],"predecessor-version":[{"id":150,"href":"https:\/\/blog.napath.com\/index.php\/wp-json\/wp\/v2\/posts\/128\/revisions\/150"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.napath.com\/index.php\/wp-json\/wp\/v2\/media\/149"}],"wp:attachment":[{"href":"https:\/\/blog.napath.com\/index.php\/wp-json\/wp\/v2\/media?parent=128"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.napath.com\/index.php\/wp-json\/wp\/v2\/categories?post=128"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.napath.com\/index.php\/wp-json\/wp\/v2\/tags?post=128"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}