Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>It may help to print out what you get from that extra step:</p> <pre><code>&gt;&gt;&gt; months_abbvs {'apr': 'April', 'aug': 'August', 'dec': 'December', 'feb': 'February', 'jan': 'January', 'jul': 'July', 'jun': 'June', 'mar': 'March', 'may': 'May', 'nov': 'November', 'oct': 'October', 'sep': 'September'} </code></pre> <p>So, you have a mapping of lowercased abbreviations to full month names.</p> <p>How does that work? Well, first, let's look at what the expression does:</p> <pre><code>&gt;&gt;&gt; m = 'December' &gt;&gt;&gt; m[:3].lower() 'dec' &gt;&gt;&gt; m[:3].lower(), m ('dec', 'December') </code></pre> <hr> <p>So, the comprehension just does that for each month:</p> <pre><code>&gt;&gt;&gt; [(m[:3].lower(), m) for m in months] [('jan', 'January'), ('feb', 'February'), ('mar', 'March'), ('apr', 'April'), ('may', 'May'), ('jun', 'June'), ('jul', 'July'), ('aug', 'August'), ('sep', 'September'), ('oct', 'October'), ('nov', 'November'), ('dec', 'December')] </code></pre> <p>As explained in more detail in <a href="http://docs.python.org/2/tutorial/datastructures.html#list-comprehensions" rel="nofollow">the tutorial</a>, a comprehension is basically shorthand for a loop. In particular, this:</p> <pre><code>&gt;&gt;&gt; m2 = [&lt;expression with m&gt; for m in months] </code></pre> <p>… is equivalent to:</p> <pre><code>&gt;&gt;&gt; m2 = [] &gt;&gt;&gt; for m in months: ... m2.append(&lt;expression with m&gt;) </code></pre> <hr> <p>Using a generator expression instead of a list comprehension just means the sequence is built as a lazy iterator instead of a list.</p> <p>And then passing the result (either way) to <code>dict</code> builds a dictionary mapping the first value of each tuple to the second.</p> <hr> <p>You could write this all a bit more readably as a dictionary comprehension:</p> <pre><code>months_abbvs = {m[:3].lower(): m for m in months} </code></pre> <p>Even better, instead of writing <code>m[:3].lower()</code> repeatedly, give it a nice name and use that:</p> <pre><code>def abbreviate(m): return m[:3].lower() months_abbvs = {abbreviate(m): m for m in months} </code></pre> <p>And then:</p> <pre><code>def valid_month(month): if month: short_month = abbreviate(month) return month_abbvs.get(short_month) </code></pre> <hr> <p>Now, what you do with your input in the new version is:</p> <pre><code>short_month = month[:3].lower() return month_abbvs.get(short_month) </code></pre> <p>Since <code>month_abbvs</code> is a <code>dict</code> (you can tell that by printing it out, or just from the fact that it was created by calling <code>dict</code> on something), the <code>get</code> method is <a href="http://docs.python.org/2/library/stdtypes.html#dict.get" rel="nofollow"><code>dict.get</code></a>. So, as explained in the linked docs, <code>month_abbvs.get(short_month)</code> is the same as <code>months_abbvs[short_month]</code>, except that if the key <code>short_month</code> is not found, you will get <code>None</code>, instead of raising an exception.</p> <p>So, if given <code>'October'</code>, you'll set <code>short_month</code> to <code>'oct'</code>. And then you look it up in the abbreviation dictionary, which returns <code>'October'</code>. If given <code>'OCT'</code> or <code>'october'</code> or <code>'octal digit string'</code>, you'll also return the same thing. Since any non-empty string is truthy, if you've done something like <code>if valid_month('October'):</code>, it will be true.</p> <p>But, if given, say, <code>'Muhammed'</code>, you'll set <code>short_month</code> to <code>'muh'</code>. And then you look that up, and it isn't there. As explained above, the <code>get</code> method returns <code>None</code> for unknown keys, so you will return <code>None</code>. Since <code>None</code> is falsey, if you've done something like <code>if valid_month('Muhammed'):</code>, it will not be true.</p> <p>In other words, it makes the function more lenient—which may be an improvement, or may be a bad thing (or may be a little of both—maybe you wanted <code>'OCT'</code> to work, but not <code>'octal digit string'</code>).</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload