{"id":113599,"date":"2020-05-30T09:17:50","date_gmt":"2020-05-30T09:17:50","guid":{"rendered":"https:\/\/blog.finxter.com\/?p=9090"},"modified":"2020-05-30T09:17:50","modified_gmt":"2020-05-30T09:17:50","slug":"how-to-check-if-a-python-list-is-empty","status":"publish","type":"post","link":"https:\/\/sickgaming.net\/blog\/2020\/05\/30\/how-to-check-if-a-python-list-is-empty\/","title":{"rendered":"How to Check If a Python List is Empty?"},"content":{"rendered":"<p>Believe it or not&#8212;how you answer this question in your day-to-day code reveals your true Python skill level to every master coder who reads your code. <\/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\/05\/truth_value_testing-1024x576.jpg\" alt=\"How to Check if List is Empty Python\" class=\"wp-image-9092\" width=\"768\" height=\"432\" srcset=\"https:\/\/blog.finxter.com\/wp-content\/uploads\/2020\/05\/truth_value_testing-scaled.jpg 1024w, https:\/\/blog.finxter.com\/wp-content\/uploads\/2020\/05\/truth_value_testing-300x169.jpg 300w, https:\/\/blog.finxter.com\/wp-content\/uploads\/2020\/05\/truth_value_testing-768x432.jpg 768w\" sizes=\"auto, (max-width: 768px) 100vw, 768px\" \/><\/figure>\n<p>Beginner coders check if a list <code>a<\/code> is empty using crude statements like <code>len(a)==0<\/code> or <code>a==[]<\/code>. While those solve the problem&#8212;they check if a list is empty&#8212;they are not what a master coder would do. Instead, the most Pythonic way to check if a list (or any other iterable for that matter) is empty is the expression <code>not a<\/code>. <\/p>\n<p>You may call it <a rel=\"noreferrer noopener\" href=\"https:\/\/docs.python.org\/3\/library\/stdtypes.html#truth-value-testing\" target=\"_blank\"><em>implicit Booleanness<\/em><\/a> (or, more formal, <strong><em>type flexibility<\/em><\/strong>): every object in Python can be implicityl converted into a truth value. <\/p>\n<p>Here&#8217;s an example in our interactive Python shell&#8212;try it yourself! <\/p>\n<p> <iframe loading=\"lazy\" src=\"https:\/\/trinket.io\/embed\/python\/c0afe4f107\" marginwidth=\"0\" marginheight=\"0\" allowfullscreen=\"\" width=\"100%\" height=\"400\" frameborder=\"0\"><\/iframe> <\/p>\n<p><em><strong>Exercise<\/strong>: What&#8217;s the output of the code if you add one element to the list <code>a<\/code>?<\/em><\/p>\n<h2>Truth Value Testing and Type Flexibility<\/h2>\n<p>Python implicitly associates any object with a Boolean value. Here are some examples:<\/p>\n<ul>\n<li>The integers 1, 2, and 3 are associated to the Boolean <code>True<\/code>.<\/li>\n<li>The integer 0 is associated to the Boolean <code>False<\/code>.<\/li>\n<li>The strings <code>'hello'<\/code>, <code>'42'<\/code>, and <code>'0'<\/code> are associated to the Boolean <code>True<\/code>.<\/li>\n<li>The empty string <code>''<\/code> is associated to the Boolean <code>False<\/code>.<\/li>\n<\/ul>\n<p>Roughly speaking, each time a Boolean value is expected, you can throw in a Python object instead. The Python object will then be converted to a Boolean value. This Boolean value will be used to decide whether to enter, say, a <code>while<\/code> loop or an <code>if<\/code> statement. This is called <strong><em>&#8220;type flexibility&#8221;<\/em><\/strong> and it&#8217;s one of Python&#8217;s core design choices.<\/p>\n<p>Per default, all objects are considered <code>True<\/code> if they are semantically non-empty. Empty objects are usually associated to the Boolean <code>False<\/code>. More specifically, only if one of the two cases is met, will the result of an object be <code>False<\/code>: (i) the <code>__len__()<\/code> function returns 0, or (ii) the <code>__bool__()<\/code> function returns <code>False<\/code>. You can redefine those two methods for each object.<\/p>\n<p>From the <a href=\"https:\/\/docs.python.org\/3\/library\/stdtypes.html#truth-value-testing\" target=\"_blank\" rel=\"noreferrer noopener\">Python documentation<\/a>, here are some common objects that are associated to the Boolean <code>False<\/code>:<\/p>\n<ul>\n<li>Defined constants: <code>None<\/code> and <code>False<\/code>.<\/li>\n<li>Zero of numerical types: <code>0<\/code>, <code>0.0<\/code>, <code>0j<\/code>, <code>Decimal(0)<\/code>, <code>Fraction(0, 1)<\/code><\/li>\n<li>Empty iterables: <code>''<\/code>, <code>()<\/code>, <code>[]<\/code>, <code>{}<\/code>, <code>set()<\/code>, <code>range(0)<\/code><\/li>\n<\/ul>\n<p>Here are some examples:<\/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=\"\">if []: print('1') if (): print('2') if [()]: print('3')\n# 3 if 0: print('4') if 0.00: print('5') if 0.001: print('6')\n# 6 if set(): print('7') if [set()]: print('8')\n# 8<\/pre>\n<p>Again, even if the iterable contains only a single element (that may evaluate to <code>False<\/code> like integer <code>0<\/code>), the implicit Boolean conversion will return <code>True<\/code> because an empty element is an element nonetheless.<\/p>\n<h2>PEP8 Recommendation: How to Check if a List is Empty<\/h2>\n<p>As some readers argued with me about how to correctly check for an empty list in Python, <a rel=\"noreferrer noopener\" href=\"https:\/\/www.python.org\/dev\/peps\/pep-0008\/\" target=\"_blank\">here<\/a>&#8216;s the explicit excerpt from the PEP8 standard (Python&#8217;s set of rules about how to write readable code):<\/p>\n<p><em>For sequences, (strings, lists, tuples), use the fact that empty sequences are false:<\/em><\/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=\"\"># Correct:\nif not seq:\nif seq:<\/pre>\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=\"\"># Wrong:\nif len(seq):\nif not len(seq):<\/pre>\n<h2>Performance Evaluations<\/h2>\n<p>To see which of the three methods is fastest, I repeated each method 100 times using the <code>timeit<\/code> library on my notebook with Intel Core i7 (TM) CPU of 8th Generation, 8GB RAM&#8212;yes, I know&#8212;and NVIDIA Graphic Card (not that it mattered).<\/p>\n<p>Here&#8217;s the 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=\"\">import timeit\nimport numpy as np setup = 'a = []' method1 = 'if len(a) == 0: pass'\nmethod2 = 'if a == []: pass'\nmethod3 = 'if not a: pass' t1 = timeit.repeat(stmt=method1, setup=setup, repeat=100)\nt2 = timeit.repeat(stmt=method2, setup=setup, repeat=100)\nt3 = timeit.repeat(stmt=method3, setup=setup, repeat=100) print('Method 1: len(a) == 0')\nprint('avg: ' + str(np.average(t1)))\nprint('var: ' + str(np.var(t1)))\nprint() print('Method 2: a == []')\nprint('avg: ' + str(np.average(t2)))\nprint('var: ' + str(np.var(t2)))\nprint() print('Method 3: not a')\nprint('avg: ' + str(np.average(t3)))\nprint('var: ' + str(np.var(t3)))\nprint()<\/pre>\n<p>The third method is the most Pythonic one with type flexibility. We measure the elapsed time of 100 executions of each method. In particular, we&#8217;re interested in the average time and the variance of the elapsed time. Both should be minimal.<\/p>\n<p>Our thesis is that the third, most Pythonic method is also the fastest because there&#8217;s no need to create a new empty list (like in method 2) or performing nested function calls like in method 1. Method 3 consists only of a single function call: converting the list into a Boolean value with the <code>__bool__<\/code> or <code>__len__<\/code> methods.<\/p>\n<p>Here&#8217;s the result in terms of elapsed average runtime and variance of the runtimes:<\/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=\"\">Method 1: len(a) == 0\navg: 0.06273576400000003\nvar: 0.00022597495215430347 Method 2: a == []\navg: 0.034635367999999944\nvar: 8.290137682917488e-05 Method 3: not a\navg: 0.017685209000000004\nvar: 6.900910317342067e-05\n<\/pre>\n<p>You can see that the third method is not only 50% faster than method 2 and 75% faster than method 3, it also has very little variance. It&#8217;s clearly the best method in terms of runtime performance. Being also the shortest method, you can now see why the method is considered to be most &#8220;Pythonic&#8221;. <\/p>\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>Believe it or not&#8212;how you answer this question in your day-to-day code reveals your true Python skill level to every master coder who reads your code. Beginner coders check if a list a is empty using crude statements like len(a)==0 or a==[]. While those solve the problem&#8212;they check if a list is empty&#8212;they are not [&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-113599","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\/113599","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=113599"}],"version-history":[{"count":0,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/posts\/113599\/revisions"}],"wp:attachment":[{"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/media?parent=113599"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/categories?post=113599"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/tags?post=113599"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}