{"id":349,"date":"2017-08-27T18:38:25","date_gmt":"2017-08-27T18:38:25","guid":{"rendered":"http:\/\/sonny.cslu.ohsu.edu\/~gormanky\/blog\/?p=349"},"modified":"2019-09-18T14:41:51","modified_gmt":"2019-09-18T14:41:51","slug":"how-why-and-when-to-flatten-your-conditionals","status":"publish","type":"post","link":"https:\/\/www.wellformedness.com\/blog\/how-why-and-when-to-flatten-your-conditionals\/","title":{"rendered":"How, why, and when to flatten your conditionals"},"content":{"rendered":"<p>You may be tempted to write code that looks a little like this:<\/p>\n<pre><code>for item in items:\r\n     if not condition_1(item):\r\n         if not condition_2(item, False):\r\n             if not condition_3(item, 3, 3):\r\n                 if not condition_4(item):\r\n                     do_work(item)<\/code><\/pre>\n<p>But please, don&#8217;t. Flatten your conditionals instead.<\/p>\n<h1>How to flatten your conditionals<\/h1>\n<p>There is a relatively straightforward alternative to the above. Instead, we use <tt>continue<\/tt>\u00a0expressions to short-circuit the cascade. This looks a little bit like this:<\/p>\n<pre><code>for item in items:\r\n     if condition_1(item):\r\n         continue\r\n     if condition_2(item, False):\r\n         continue\r\n     if condition_3(item, 3, 3):\r\n         continue\r\n     if condition_4(item):\r\n         continue\r\n     do_work(item)<\/code><\/pre>\n<p>That&#8217;s pretty much all there&#8217;s to it.<\/p>\n<p>Perhaps you&#8217;re not inside of a loop, but rather inside of a &#8220;nullable&#8221; function or method (i.e., one which may reasonably return <span style=\"font-family: monospace;\">None<\/span>); \u00a0that&#8217;s okay, replace <tt>continue<\/tt> with <tt>return<\/tt>. Perhaps there&#8217;s more than one <tt>item<\/tt> you&#8217;re possibly shipping off to <tt>do_work<\/tt> on; that&#8217;s okay, wrap the conditionals in a function and use <tt>return<\/tt> to short-circuit evaluation. Perhaps you want to terminal the entire loop, not just this iteration thereof; that&#8217;s okay, replace <tt>continue<\/tt> with <tt>break<\/tt>.<\/p>\n<h1>Why to flatten your conditionals<\/h1>\n<p>The flattened loop is much easier to read. There is no indentation (or bracketing) to track. The fact that each of the conditional expressions is at the same indentation (bracketing) level makes it clear that we&#8217;re just dealing with a cascade of conditionals, all of which are handled the same. Realistically, one can only visually parse 3-4 levels of indentation; <a href=\"https:\/\/www.kernel.org\/doc\/html\/v4.10\/process\/coding-style.html#indentation\">the Linux kernel, for example, uses an 8-character indent and forbids more than 3 levels of indentation<\/a>. Flattening your conditionals means you don&#8217;t have to deal with that very often.<\/p>\n<h1>When to flatten your conditionals<\/h1>\n<p>It&#8217;s perhaps preferable to write your early code with nested conditional statements. It may turn out that you need to do some work in one of the medial <tt>else:<\/tt> clauses (which we&#8217;ve elided here), which can make flattening the conditionals hard. But once you&#8217;re writing comments about the conditionals in the cascade, and preparing to share your code with others, it&#8217;s time to do away with more than a few layers of indentation.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>You may be tempted to write code that looks a little like this: for item in items: if not condition_1(item): if not condition_2(item, False): if not condition_3(item, 3, 3): if not condition_4(item): do_work(item) But please, don&#8217;t. Flatten your conditionals instead. How to flatten your conditionals There is a relatively straightforward alternative to the above. Instead, &hellip; <a href=\"https:\/\/www.wellformedness.com\/blog\/how-why-and-when-to-flatten-your-conditionals\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;How, why, and when to flatten your conditionals&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_crdt_document":"","footnotes":""},"categories":[3,8],"tags":[],"class_list":["post-349","post","type-post","status-publish","format-standard","hentry","category-dev","category-python"],"_links":{"self":[{"href":"https:\/\/www.wellformedness.com\/blog\/wp-json\/wp\/v2\/posts\/349","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.wellformedness.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.wellformedness.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.wellformedness.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.wellformedness.com\/blog\/wp-json\/wp\/v2\/comments?post=349"}],"version-history":[{"count":4,"href":"https:\/\/www.wellformedness.com\/blog\/wp-json\/wp\/v2\/posts\/349\/revisions"}],"predecessor-version":[{"id":813,"href":"https:\/\/www.wellformedness.com\/blog\/wp-json\/wp\/v2\/posts\/349\/revisions\/813"}],"wp:attachment":[{"href":"https:\/\/www.wellformedness.com\/blog\/wp-json\/wp\/v2\/media?parent=349"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.wellformedness.com\/blog\/wp-json\/wp\/v2\/categories?post=349"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.wellformedness.com\/blog\/wp-json\/wp\/v2\/tags?post=349"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}