Python loops can have else clause?!
I write a lot of Python. I also write a lot of JavaScript. As I switch between the two (often several times in a day) I sometimes find myself trying to do something in one using the syntax of the other. The most common example is joining a list.
Python:
' '.join(['foo', 'bar'])
JavaScript:
['foo', 'bar'].join(' ')
Often — as is the case above — the syntactical differences are minor, but there are times when there's no direct translation.
MooTools, for example, adds the every method to the Array object.
This makes it possible to write some rather terse conditional statements.
var numbers = [87, 33, 21, 75]; if (numbers.every(function (n) { return n % 3 == 0; })) { window.alert('The numbers are all divisible by 3.'); }
Python lists have no comparable method, so how would one write this in Python?
numbers = [87, 33, 21, 75] if [n for n in numbers if n % 3 == 0] == numbers: print 'The numbers are all divisible by 3.'
This approach involves using a list comprehension to create a list of numbers
which are divisible by 3, and comparing this list to numbers. If the lists
are equal, everything in numbers is divisible by 3.
Now for something a bit more challenging
Assume that we have a list of documents, and we want to know which of the documents contain all the terms in a list of search terms.
// (MooTools) JavaScript var terms = ['python', 'list', 'methods'], matches = []; documents.each(function (document) { if (terms.every(function (term) { return document.body.indexOf(term) != -1; })) matches.append(document); });
Here, we could use the list comprehension approach as before.
# Python terms = ['python', 'list', 'methods'] matches = [] for document in documents: if [t for t in terms if document.body.find(t) != -1] == terms: matches.append(document)
This is reasonably succinct, but not terribly efficient since each document is checked for every search term. Given that we're not interested in documents that lack even a single search term, it should be possible to rewrite this code so that we don't waste time on lost causes.
It turns out that Python has just the thing for the job: in Python, a loop
statements may have an else clause!
terms = ['python', 'list', 'methods'] matches = [] for document in documents: for term in terms: if document.body.find(term) == -1: break else: # every term was found matches.append(document)
From 4. More Control Flow Tools:
Loop statements may have an
elseclause; it is executed when the loop terminates through exhaustion of the list (withfor) or when the condition becomes false (withwhile), but not when the loop is terminated by abreakstatement.
I'm looking forward to finding more good spots to make use of else
clauses with my Python loops. :D
Possibly related posts
- Self-caching functions in JavaScript and Python
- Converting integers to ordinals
- Filtering lists in Python, Ruby, and JavaScript
- MooTools every method
- Bitwise NOT operator proves useful in JavaScript