{"id":1614,"date":"2021-05-07T16:20:43","date_gmt":"2021-05-07T23:20:43","guid":{"rendered":"https:\/\/coderpad.io\/?p=1614"},"modified":"2024-01-06T14:30:11","modified_gmt":"2024-01-06T22:30:11","slug":"python-list-comprehension-guide","status":"publish","type":"post","link":"https:\/\/coderpad.io\/blog\/development\/python-list-comprehension-guide\/","title":{"rendered":"Python List Comprehension &#8211; The Comprehensive Guide"},"content":{"rendered":"\n<p>Python list comprehensions allow for powerful and readable list mutations. In this article, we&#8217;ll learn many different ways in how they can be used and where they&#8217;re most useful.&nbsp;<\/p>\n\n\n\n<p>Python is an incredibly powerful language that\u2019s widely adopted across a wide range of applications. As with any language of sufficient complexity, Python enables multiple ways of doing things. However, the community at large has agreed that code should follow a specific pattern: be \u201cPythonic\u201d. While \u201cPythonic\u201d is a community term, the official language defines what they call <a href=\"https:\/\/www.python.org\/dev\/peps\/pep-0020\/\" target=\"_blank\" rel=\"noopener\">\u201cThe Zen of Python\u201d in PEP 20<\/a>. To quote just a small bit of it:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote\">\n<p>Explicit is better than implicit.<\/p>\n\n\n\n<p>Simple is better than complex.<\/p>\n\n\n\n<p>Complex is better than complicated.<\/p>\n\n\n\n<p>Flat is better than nested.<\/p>\n<\/blockquote>\n\n\n\n<p><br>Introduced in Python 2.0 with <a href=\"https:\/\/www.python.org\/dev\/peps\/pep-0202\/\" target=\"_blank\" rel=\"noopener\">PEP 202<\/a>, list comprehensions help align some of these goals for common operations in Python. Let\u2019s explore how we can use list comprehensions and where they serve the Zen of Python better than alternatives.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What is List Comprehension?<\/h2>\n\n\n\n<p><br>Let\u2019s say that we want to make an array of numbers, counting up from 0 to 2. We could assign an empty array, use <code>range<\/code> to create a generator, then <code>append<\/code> to that array using a <code>for<\/code> loop<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python shcb-wrap-lines\">numbers = &#91;]\n<span class=\"hljs-keyword\">for<\/span> x <span class=\"hljs-keyword\">in<\/span> range(<span class=\"hljs-number\">3<\/span>):\n    numbers.append(x)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Alternatively, we could use list comprehension to shorten that to one line of code.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python shcb-wrap-lines\">numbers = &#91;x <span class=\"hljs-keyword\">for<\/span> x <span class=\"hljs-keyword\">in<\/span> range(<span class=\"hljs-number\">3<\/span>)]<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Confused on the syntax? Let\u2019s outline what\u2019s happening token-by-token.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/coderpad.io\/wp-content\/uploads\/2021\/05\/img_6094fcc2be38c.png\" alt=\"Breakdown of a list comprehension explained more below\"\/><\/figure>\n\n\n\n<p>The first and last brackets simply indicate that this is a list comprehension. This is also how I remember that a list comprehension outputs an array &#8211; it looks like we\u2019re constructing an array with logic inside.<\/p>\n\n\n\n<p>Second, we have the \u201cx\u201d before the \u201cfor\u201d. This is the return value. This means that if we change the comprehension to:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python shcb-wrap-lines\">numbers = &#91;x*<span class=\"hljs-number\">2<\/span> <span class=\"hljs-keyword\">for<\/span> x <span class=\"hljs-keyword\">in<\/span> range(<span class=\"hljs-number\">3<\/span>)]<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Instead of \u201c0, 1, 2\u201d, we\u2019d get \u201c0, 2, 4\u201d.<\/p>\n\n\n\n<p>Next up, we have a declaration of a <code>for<\/code> loop. This comprises of three separate parts:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u201cfor\u201d &#8211; the start of the loop<\/li>\n\n\n\n<li>\u201cx\u201d &#8211; declaring the name of the variable to assign in each iteration<\/li>\n\n\n\n<li>\u201cin\u201d &#8211; denoting the start of listening for the iterator<\/li>\n<\/ol>\n\n\n\n<p>Finally, we have the <code>range<\/code>. This acts as the iterator for the <code>for<\/code> loop to iterate through. This can be replaced with anything a <code>for<\/code> loop can go through: a list, a tuple, or anything else that implements the iterator interface.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Are List Comprehension Pythonic?<\/h2>\n\n\n\n<p>While it might seem counterintuitive to learn a new syntax for manipulating lists, let\u2019s look at what the alternative looks like. Using <code>map<\/code>, we can pass an anonymous function (lambda) to multiply a number by 2, pass the <code>range<\/code> to iterate through. However, once this is done, we\u2019re left with a <code>map<\/code> object. In order to convert this back to a list, we have to wrap that method in <code>list<\/code>.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python shcb-wrap-lines\">numbers = list(map(<span class=\"hljs-keyword\">lambda<\/span> x: x*<span class=\"hljs-number\">2<\/span>, range(<span class=\"hljs-number\">3<\/span>)))<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Compare this to the list comprehension version:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python shcb-wrap-lines\">numbers = &#91;x*<span class=\"hljs-number\">2<\/span> <span class=\"hljs-keyword\">for<\/span> x <span class=\"hljs-keyword\">in<\/span> range(<span class=\"hljs-number\">3<\/span>)]<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Looking at the comprehension, it\u2019s significantly more readable at a glance. Thinking back to The Zen of Python, \u201cSimple is better than complex,\u201d list comprehensions seem to be more Pythonic than using <code>map<\/code>.<\/p>\n\n\n\n<p>While others might argue that a \u201cfor\u201d loop might be easier to read, the Zen of Python also mentions \u201cFlat is better than nested\u201d. Because of this, list comprehensions for simple usage like this are more Pythonic.<\/p>\n\n\n\n<p>Now that we\u2019re more familiar with basic usage of list comprehension, let\u2019s dive into some of it\u2019s more powerful capabilities.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Filtering<\/h2>\n\n\n\n<p>While it might seem like list comprehension is only capable of doing a 1:1 match like <code>map<\/code>, you\u2019re actually able to implement logic more similar to <code>filter<\/code> to change how many items are in the output compared to what was input.<\/p>\n\n\n\n<p>If we add an <code>if<\/code> to the end of the statement, we can limit the output to only even numbers:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python shcb-wrap-lines\">even_numbers = &#91;x <span class=\"hljs-keyword\">for<\/span> x <span class=\"hljs-keyword\">in<\/span> range(<span class=\"hljs-number\">10<\/span>) <span class=\"hljs-keyword\">if<\/span> x%<span class=\"hljs-number\">2<\/span>==<span class=\"hljs-number\">0<\/span>] <span class=\"hljs-comment\">#&#91;0, 2, 4, 6, 8]<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>This can of course be combined with the changed mutation value:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python shcb-wrap-lines\">double_even_numbers = &#91;x*<span class=\"hljs-number\">2<\/span> <span class=\"hljs-keyword\">for<\/span> x <span class=\"hljs-keyword\">in<\/span> range(<span class=\"hljs-number\">10<\/span>) <span class=\"hljs-keyword\">if<\/span> x%<span class=\"hljs-number\">2<\/span>==<span class=\"hljs-number\">0<\/span>] <span class=\"hljs-comment\">#&#91;0, 4, 8, 12, 16]<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Conditionals<\/h2>\n\n\n\n<p>While filtering might seem like the only usage of <code>if<\/code> in a list comprehension, you\u2019re able to use them to act as conditionals to return different values from the original.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python shcb-wrap-lines\">number_even_odd = &#91;<span class=\"hljs-string\">\"Even\"<\/span> <span class=\"hljs-keyword\">if<\/span> x % <span class=\"hljs-number\">2<\/span> == <span class=\"hljs-number\">0<\/span> <span class=\"hljs-keyword\">else<\/span> <span class=\"hljs-string\">\"Odd\"<\/span> <span class=\"hljs-keyword\">for<\/span> x <span class=\"hljs-keyword\">in<\/span> range(<span class=\"hljs-number\">4<\/span>)]\n<span class=\"hljs-comment\"># &#91;\"Even\", \"Odd\", \"Even\", \"Odd\"]<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Keep in mind, you could even combine this ternary method with the previous filtering <code>if<\/code>:<br><\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python shcb-wrap-lines\">thirds_even_odd = &#91;<span class=\"hljs-string\">\"Even\"<\/span> <span class=\"hljs-keyword\">if<\/span> x % <span class=\"hljs-number\">2<\/span> == <span class=\"hljs-number\">0<\/span> <span class=\"hljs-keyword\">else<\/span> <span class=\"hljs-string\">\"Odd\"<\/span> <span class=\"hljs-keyword\">for<\/span> x <span class=\"hljs-keyword\">in<\/span> range(<span class=\"hljs-number\">10<\/span>) <span class=\"hljs-keyword\">if<\/span> x%<span class=\"hljs-number\">3<\/span>==<span class=\"hljs-number\">0<\/span>]\n<span class=\"hljs-comment\"># &#91;0, 3, 6, 9] after filtering numbers<\/span>\n<span class=\"hljs-comment\"># &#91;\"Even\", \"Odd\", \"Even\", \"Odd\"] after ternary to string<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>If we wanted to expand this code to use full-bodied functions, it would look something like this:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python shcb-wrap-lines\">thirds_even_odd = &#91;]\n<span class=\"hljs-keyword\">for<\/span> x <span class=\"hljs-keyword\">in<\/span> range(<span class=\"hljs-number\">10<\/span>):\n    <span class=\"hljs-keyword\">if<\/span> x%<span class=\"hljs-number\">3<\/span>==<span class=\"hljs-number\">0<\/span>:\n        <span class=\"hljs-keyword\">if<\/span> x%<span class=\"hljs-number\">2<\/span>==<span class=\"hljs-number\">0<\/span>:\n            thirds_even_odd.append(<span class=\"hljs-string\">\"Even\"<\/span>)\n        <span class=\"hljs-keyword\">else<\/span>:\n            thirds_even_odd.append(<span class=\"hljs-string\">\"Odd\"<\/span>)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Nested Loops<\/h2>\n\n\n\n<p>While we explained that you\u2019re able to have less items in the output than the input in our \u201cfiltering\u201d section, you\u2019re able to do the opposite as well. Here, we\u2019re able to nest two \u201cfor\u201d loops on top of each other in order to have a longer output than our initial input.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python shcb-wrap-lines\">repeated_list = &#91;y <span class=\"hljs-keyword\">for<\/span> x <span class=\"hljs-keyword\">in<\/span> &#91;<span class=\"hljs-string\">\"\"<\/span>, <span class=\"hljs-string\">\"\"<\/span>] <span class=\"hljs-keyword\">for<\/span> y <span class=\"hljs-keyword\">in<\/span> &#91;<span class=\"hljs-number\">1<\/span>, <span class=\"hljs-number\">2<\/span>, <span class=\"hljs-number\">3<\/span>]]\n<span class=\"hljs-comment\"># &#91;1, 2, 3, 1, 2, 3]<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>This logic allows you to iterate through two different arrays and output the final value in the nested loop. If we have to rewrite this, we\u2019d write it out as:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python shcb-wrap-lines\">repeated_list = &#91;]\n<span class=\"hljs-keyword\">for<\/span> x <span class=\"hljs-keyword\">in<\/span> &#91;<span class=\"hljs-string\">\"\"<\/span>, <span class=\"hljs-string\">\"\"<\/span>]:\n    <span class=\"hljs-keyword\">for<\/span> y <span class=\"hljs-keyword\">in<\/span> &#91;<span class=\"hljs-number\">1<\/span>, <span class=\"hljs-number\">2<\/span>, <span class=\"hljs-number\">3<\/span>]:\n        repeated_list.append(y)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>This allows us to nest the loops and keep the logic flat. However, you\u2019ll notice in this example, we\u2019re not utilizing the \u201cx\u201d variable. Let\u2019s change that and do a calculations based on the \u201cx\u201d variable as well:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-13\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python shcb-wrap-lines\">numbers_doubled = &#91;y <span class=\"hljs-keyword\">for<\/span> x <span class=\"hljs-keyword\">in<\/span> &#91;<span class=\"hljs-number\">1<\/span>, <span class=\"hljs-number\">2<\/span>] <span class=\"hljs-keyword\">for<\/span> y <span class=\"hljs-keyword\">in<\/span> &#91;x, x*<span class=\"hljs-number\">2<\/span>]]\n<span class=\"hljs-comment\"># 1, 2, 2, 4<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-13\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Now that we\u2019ve explored using hard-coded arrays to nest loops, let\u2019s go one level deeper and see how we can utilize list comprehensions in a nested manner.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Nested Comprehensions<\/h2>\n\n\n\n<p>There are two facts that we can combine to provide list comprehension with a super power:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>You can use lists inside of a list comprehension<\/li>\n\n\n\n<li>List comprehensions returns lists<\/li>\n<\/ol>\n\n\n\n<p>Combining these leads to the natural conclusion that you can nest list comprehensions inside of other list comprehensions.<\/p>\n\n\n\n<p>For example, let\u2019s take the following logic that, given a two-dimensional list, returns all of the first index items in one list and the second indexed items in a second list.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-14\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python shcb-wrap-lines\">row_list = &#91;&#91;<span class=\"hljs-number\">1<\/span>, <span class=\"hljs-number\">2<\/span>], &#91;<span class=\"hljs-number\">3<\/span>,<span class=\"hljs-number\">4<\/span>], &#91;<span class=\"hljs-number\">5<\/span>,<span class=\"hljs-number\">6<\/span>]]\nindexed_list = &#91;]\n<span class=\"hljs-keyword\">for<\/span> i <span class=\"hljs-keyword\">in<\/span> range(<span class=\"hljs-number\">2<\/span>):\n    indexed_row = &#91;]\n    <span class=\"hljs-keyword\">for<\/span> row <span class=\"hljs-keyword\">in<\/span> row_list:\n        indexed_row.append(row&#91;i])\n    indexed_list.append(indexed_row)\n\nprint(indexed_list)\n<span class=\"hljs-comment\"># &#91;&#91;1, 3, 5], &#91;2, 4, 6]]<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-14\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>You\u2019ll notice that the first indexed items (<code>1<\/code>, <code>3<\/code>, <code>5<\/code>) are in the first array, and the second indexed items (<code>2<\/code>, <code>4<\/code>, <code>6<\/code>) are in the second array.<\/p>\n\n\n\n<p>Let\u2019s take that and convert it to a list comprehension:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-15\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python shcb-wrap-lines\">row_list = &#91;&#91;<span class=\"hljs-number\">1<\/span>, <span class=\"hljs-number\">2<\/span>], &#91;<span class=\"hljs-number\">3<\/span>,<span class=\"hljs-number\">4<\/span>], &#91;<span class=\"hljs-number\">5<\/span>,<span class=\"hljs-number\">6<\/span>]]\nindexed_list = &#91;&#91;row&#91;i] <span class=\"hljs-keyword\">for<\/span> row <span class=\"hljs-keyword\">in<\/span> row_list] <span class=\"hljs-keyword\">for<\/span> i <span class=\"hljs-keyword\">in<\/span> range(<span class=\"hljs-number\">2<\/span>)]\nprint(indexed_list)\n<span class=\"hljs-comment\"># &#91;&#91;1, 3, 5], &#91;2, 4, 6]]<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-15\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Readable Actions and Other Operators<\/h2>\n\n\n\n<p>Something you may have noticed while working with list comprehension is how close some of these operators are to a typical sentence. While basic comprehensions serve this well on their own, they\u2019re advanced by the likes of Python\u2019s other grammatical-style operators. For example, operators may include:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>and<\/code> &#8211; Logical \u201cand\u201d<\/li>\n\n\n\n<li><code>or<\/code> &#8211; Logical \u201cor\u201d<\/li>\n\n\n\n<li><code>not<\/code> &#8211; Logical \u201cnot\u201d<\/li>\n\n\n\n<li><code>is<\/code> &#8211; Equality check<\/li>\n\n\n\n<li><code>in<\/code> &#8211; Membership check\/second half of <code>for<\/code> loop<\/li>\n<\/ul>\n\n\n\n<p>These can be used for great effect. Let\u2019s look at some options we could utilize:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-16\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python shcb-wrap-lines\">vowels = <span class=\"hljs-string\">'aeiou'<\/span>\nword = <span class=\"hljs-string\">\"Hello!\"<\/span>\n\nword_vowels = &#91;letter <span class=\"hljs-keyword\">for<\/span> letter <span class=\"hljs-keyword\">in<\/span> word <span class=\"hljs-keyword\">if<\/span> letter.lower() <span class=\"hljs-keyword\">in<\/span> vowels]\n\nprint(word_vowels)\n\n<span class=\"hljs-comment\"># &#91;'e', 'o']<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-16\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Alternatively we could check for consonants instead, simply by adding one \u201cnot\u201d:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-17\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python shcb-wrap-lines\">word_consonants = &#91;letter <span class=\"hljs-keyword\">for<\/span> letter <span class=\"hljs-keyword\">in<\/span> word <span class=\"hljs-keyword\">if<\/span> letter.lower() <span class=\"hljs-keyword\">not<\/span> <span class=\"hljs-keyword\">in<\/span> vowels]\n<span class=\"hljs-comment\"># &#91;'H', 'l', 'l']<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-17\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Finally, to showcase boolean logic, we\u2019ll do a slight contrived check for numbers that mod 2 and 3 perfectly but are not 4:<br><\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-18\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python shcb-wrap-lines\">restricted_number = <span class=\"hljs-number\">4<\/span>\n\nsafe_numbers = &#91;x <span class=\"hljs-keyword\">for<\/span> x <span class=\"hljs-keyword\">in<\/span> range(<span class=\"hljs-number\">6<\/span>) <span class=\"hljs-keyword\">if<\/span> (x%<span class=\"hljs-number\">2<\/span>==<span class=\"hljs-number\">0<\/span> <span class=\"hljs-keyword\">or<\/span> x%<span class=\"hljs-number\">3<\/span>==<span class=\"hljs-number\">0<\/span>) <span class=\"hljs-keyword\">and<\/span> x <span class=\"hljs-keyword\">is<\/span> <span class=\"hljs-keyword\">not<\/span> restricted_number]\n\n<span class=\"hljs-comment\"># &#91;0, 2, 3]<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-18\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Conclusion &amp; Challenge<\/h2>\n\n\n\n<p><br>We\u2019ve covered a lot about list comprehension in Python today! We\u2019re able to build complex logic into our applications while maintaining readability in most situations. However, like any tool, list comprehension can be abused. When you start including too many logical operations to comfortably read, you should likely migrate away from list comprehension to use full-bodied <code>for<\/code> loops.<br><br>For example, given this sandbox code pad of a long and messy list comprehension, how can you refactor to remove all usage of list comprehensions? Avoid using <code>map<\/code>, <code>filter<\/code> or other list helpers, either. Simply use nested <code>for<\/code> loops and <code>if<\/code> conditionals to match the behavior as it was before.<\/p>\n\n\n<div\n\tclass=\"sandbox-embed responsive-embed  sandbox-embed--full-width\"\n\tstyle=\"padding-top: 85%\"\ndata-block-name=\"coderpad-sandbox-embed\">\n\t<iframe src=\"https:\/\/embed.coderpad.io\/sandbox?question_id=177671&#038;use_question_button\" width=\"640\" height=\"544\" loading=\"lazy\" aria-label=\"Try out the CoderPad sandbox\"><\/iframe>\n<\/div>\n\n\n\n<p>This is an open-ended question meant to challenge your skills you\u2019ve learned throughout the article!<\/p>\n\n\n\n<p>Stuck? Wanting to share your solution? <a href=\"https:\/\/bit.ly\/coderpad-slack\" target=\"_blank\" rel=\"noopener\">Join our community Slack<\/a>, where you can talk about list comprehensions and the challenge in-depth with the CoderPad team!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Let\u2019s explore how we can use list comprehensions and where they serve the Zen of Python better than alternatives.<\/p>\n","protected":false},"author":1,"featured_media":2212,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[9],"tags":[],"persona":[29],"blog-programming-language":[37],"keyword-cluster":[],"class_list":["post-1614","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-development"],"acf":[],"_links":{"self":[{"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/posts\/1614","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/comments?post=1614"}],"version-history":[{"count":15,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/posts\/1614\/revisions"}],"predecessor-version":[{"id":38064,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/posts\/1614\/revisions\/38064"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/media\/2212"}],"wp:attachment":[{"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/media?parent=1614"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/categories?post=1614"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/tags?post=1614"},{"taxonomy":"persona","embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/persona?post=1614"},{"taxonomy":"blog-programming-language","embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/blog-programming-language?post=1614"},{"taxonomy":"keyword-cluster","embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/keyword-cluster?post=1614"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}