{"id":114621,"date":"2020-06-25T12:45:52","date_gmt":"2020-06-25T12:45:52","guid":{"rendered":"https:\/\/blog.finxter.com\/?p=10063"},"modified":"2020-06-25T12:45:52","modified_gmt":"2020-06-25T12:45:52","slug":"the-most-pythonic-way-to-check-if-two-unordered-lists-are-identical","status":"publish","type":"post","link":"https:\/\/sickgaming.net\/blog\/2020\/06\/25\/the-most-pythonic-way-to-check-if-two-unordered-lists-are-identical\/","title":{"rendered":"The Most Pythonic Way to Check if Two Unordered Lists Are Identical"},"content":{"rendered":"<p class=\"has-luminous-vivid-amber-background-color has-background\">To check if two unordered lists <code>x<\/code> and <code>y<\/code> are identical, compare the converted sets with <code>set(x) == set(y)<\/code>. However, this loses all information about duplicated elements. To consider duplicates, compare the sorted lists with <code>sorted(x) == sorted(y)<\/code>. Due to the efficient merge-sort-like implementation of the <code>sorted()<\/code> function, this is quite fast for almost-sorted lists.<\/p>\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.finxter.com\/wp-content\/uploads\/2020\/06\/probform_ordered_identical_lists-1024x576.jpg\" alt=\"\" class=\"wp-image-10097\" width=\"768\" height=\"432\" srcset=\"https:\/\/blog.finxter.com\/wp-content\/uploads\/2020\/06\/probform_ordered_identical_lists-scaled.jpg 1024w, https:\/\/blog.finxter.com\/wp-content\/uploads\/2020\/06\/probform_ordered_identical_lists-300x169.jpg 300w, https:\/\/blog.finxter.com\/wp-content\/uploads\/2020\/06\/probform_ordered_identical_lists-768x432.jpg 768w\" sizes=\"auto, (max-width: 768px) 100vw, 768px\" \/><\/figure>\n<p><strong>Problem<\/strong>: Given are two <a href=\"https:\/\/blog.finxter.com\/python-lists\/\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"The Ultimate Guide to Python Lists\">lists <\/a><code>x<\/code> and <code>y<\/code>. You want to return <code>True<\/code> if both lists contain the same elements, and otherwise <code>False<\/code>. A variant of this problem is to ignore <a href=\"https:\/\/blog.finxter.com\/how-to-remove-duplicates-from-a-python-list-of-lists\/\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"How to Remove Duplicates From a Python List of Lists?\">duplicates <\/a>(which makes this problem far simpler).<\/p>\n<p><strong>Examples<\/strong>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">x = [1, 2, 3, 4, 5]\ny = [1, 2, 3]\n# compare(x, y) --> False x = [1, 2, 3, 4, 5]\ny = [1, 2, 3, 5, 4]\n# compare(x, y) --> True x = [1, 2, 3, 4, 5]\ny = [1, 2, 3, 4, 5]\n# compare(x, y) --> True<\/pre>\n<p>Let&#8217;s discuss the most Pythonic ways of solving this problem. Here&#8217;s a quick interactive code overview:<\/p>\n<p> <iframe loading=\"lazy\" src=\"https:\/\/trinket.io\/embed\/python\/326d676c69\" width=\"100%\" height=\"700\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" allowfullscreen><\/iframe> <\/p>\n<p><em><strong>Exercise<\/strong>: Glance over all methods and run the code. What questions come to mind? Do you understand each method?<\/em><\/p>\n<p>Read on to learn about each method in detail!<\/p>\n<h2>Method 1: Set Conversion<\/h2>\n<p>This method assumes that you ignore duplicates. So, the lists <code>[1, 1, 1]<\/code> and <code>[1]<\/code> are considered to be identical:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">###################\n# 1. Set Conversion\n###################\ndef method_1(x, y): return set(x) == set(y) print(method_1([1, 2, 3], [1, 2]))\n# False print(method_1([1, 2], [2, 1]))\n# True<\/pre>\n<p>Converting the list to a set has linear runtime complexity. Comparing two sets for equality also has linear runtime complexity (due to the <a href=\"https:\/\/blog.finxter.com\/complexity-of-python-operations\/\" title=\"Complexity of Python Operations\" target=\"_blank\" rel=\"noreferrer noopener\">constant runtime complexity of set membership<\/a>). So, overall, the runtime complexity of this method is linear in the number of elements in the larger list.<\/p>\n<p>However, a set doesn&#8217;t contain any information about the number of times each element is represented. To consider this information, you&#8217;ll need a multiset data structure. <\/p>\n<h2>Method 2: Multiset with Collections Counter<\/h2>\n<p>In Python, there are some <a href=\"https:\/\/pythonhosted.org\/multiset\/\" title=\"https:\/\/pythonhosted.org\/multiset\/\" target=\"_blank\" rel=\"noreferrer noopener\">multiset <\/a>packages that are capable of considering the number of times each element is represented in the original list. One of them is the <code>collections.Counter<\/code> class. <\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">###################\n# 2. Collections Counter\n################### import collections def method_2(x, y): return collections.Counter(x) == collections.Counter(y) print(method_2([1, 1, 1], [1, 1]))\n# False print(method_2([1, 2, 3], [2, 1, 3]))\n# True<\/pre>\n<p>This method is also efficient and it hides implementation details which leads to a higher degree of decoupling in your Python application. However, you may not like that it requires to import another dependency.<\/p>\n<h2>Method 3: Sorting<\/h2>\n<p>Sorting a list in Python uses a highly efficient algorithm based on mergesort. This means that if the list is &#8220;almost&#8221; sorted, the sorting routine is very fast. Only in the absolute worst case, the <a href=\"https:\/\/blog.finxter.com\/runtime-complexity-of-python-list-methods-easy-table-lookup\/\" title=\"Runtime Complexity of Python List Methods [Easy Table Lookup]\" target=\"_blank\" rel=\"noreferrer noopener\">computational complexity<\/a> is <em>O(n log n)<\/em> to sort a list.<\/p>\n<p>As soon as both lists are sorted, you can go on and use the element-wise comparison operator <code>x==y<\/code> to <a href=\"https:\/\/blog.finxter.com\/check-if-two-ordered-lists-are-identical\/\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"The Most Pythonic Way to Check if Two Ordered Lists Are Identical\">check identity of two ordered lists<\/a> <code>x<\/code> and <code>y<\/code>. <\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">###################\n# 3. Sorting\n################### def method_3(x, y): return sorted(x) == sorted(y) print(method_2([1, 1, 1], [1, 1]))\n# False print(method_2([1, 2, 3], [2, 1, 3]))\n# True<\/pre>\n<p>Thanks for reading this article! If you want to learn something new every day, <a href=\"https:\/\/blog.finxter.com\/subscribe\/\" title=\"Subscribe\" target=\"_blank\" rel=\"noreferrer noopener\">join my free Python email series<\/a> for continuous improvement in Python and computer science.<\/p>\n<h2>Related Video<\/h2>\n<p>This video is related to the problem: <a href=\"https:\/\/blog.finxter.com\/check-if-two-ordered-lists-are-identical\/\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"The Most Pythonic Way to Check if Two Ordered Lists Are Identical\">checking if two <strong><em>ordered <\/em><\/strong>lists are identical<\/a>.<\/p>\n<figure class=\"wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\">\n<div class=\"wp-block-embed__wrapper\">\n<div class=\"ast-oembed-container\"><iframe loading=\"lazy\" title=\"The Most Pythonic Way to Check if Two Ordered Lists Are Identical\" width=\"1400\" height=\"788\" src=\"https:\/\/www.youtube.com\/embed\/RkLh-6ylaUg?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe><\/div>\n<\/div>\n<\/figure>\n<h2>Where to Go From Here?<\/h2>\n<p>Enough theory, let\u2019s get some practice!<\/p>\n<p>To become successful in coding, you need to get out there and solve real problems for real people. That\u2019s how you can become a six-figure earner easily. And that\u2019s how you polish the skills you really need in practice. After all, what\u2019s the use of learning theory that nobody ever needs?<\/p>\n<p><strong>Practice projects is how you sharpen your saw in coding!<\/strong><\/p>\n<p>Do you want to become a code master by focusing on practical code projects that actually earn you money and solve problems for people?<\/p>\n<p>Then become a Python freelance developer! It\u2019s the best way of approaching the task of improving your Python skills\u2014even if you are a complete beginner.<\/p>\n<p>Join my free webinar <a rel=\"noreferrer noopener\" href=\"https:\/\/blog.finxter.com\/webinar-freelancer\/\" target=\"_blank\">\u201cHow to Build Your High-Income Skill Python\u201d<\/a> and watch how I grew my coding business online and how you can, too\u2014from the comfort of your own home.<\/p>\n<p><a href=\"https:\/\/blog.finxter.com\/webinar-freelancer\/\" target=\"_blank\" rel=\"noreferrer noopener\">Join the free webinar now!<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>To check if two unordered lists x and y are identical, compare the converted sets with set(x) == set(y). However, this loses all information about duplicated elements. To consider duplicates, compare the sorted lists with sorted(x) == sorted(y). Due to the efficient merge-sort-like implementation of the sorted() function, this is quite fast for almost-sorted lists. [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[857],"tags":[73,468,528],"class_list":["post-114621","post","type-post","status-publish","format-standard","hentry","category-python-tut","tag-programming","tag-python","tag-tutorial"],"_links":{"self":[{"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/posts\/114621","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/comments?post=114621"}],"version-history":[{"count":0,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/posts\/114621\/revisions"}],"wp:attachment":[{"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/media?parent=114621"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/categories?post=114621"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/tags?post=114621"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}