List Comprehension
Well here I go again re-learning some stuff. I love list comprehension. I just did a challenge on some website where the description was:
The main idea is to count all the occurring characters in a string. If you have a string like aba, then the result should be {‘a’: 2, ‘b’: 1}.
What if the string is empty? Then the result should be empty object literal, {}.
So I of course went through and did my for loop, and nested an if/else within and some other stuff that wasn’t terribly elegant. It wans’t bad but it wasn’t very elegant. Then after completing said challenge other people’s solutions the good stuff was revealed to me (I love that part).
The best solution was one that imported a library but I liked this one better:
return {i: string.count(i) for i in string}
It’s a list comprehension. The idea is to populate an iterable (list, tuple, set or dictionary) with values in a simpler manner, no lingering variables when we’re done, just the one list/dict/whatever that we wanted. Python documentation says:
Note that this creates (or overwrites) a variable named x that still exists after the loop completes.
And we see that x
does in fact linger:
>>> for x in range(3):
... print(x)
...
0
1
2
>>> x
2
So let’s build it this way:
myList = [value for value in iterable]
So that each value in the iterable will be added as an item to myList. And no lingering variables to speak of:
>>> myList = [value for value in range(3)]
>>> myList
[0, 1, 2]
>>> value
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'value' is not defined
We can do this to a string because strings in fact have the __iter__
method (which may be obvious to many but I still find it interesting):
>>> myString = 'asdf'
>>> hasattr(myString,"__iter__")
True
Another thing I find interesting about list comprehensions is that they’re modifiable. I’ve got this in some old notes of mine:
friends = ["Rolf", "Bob", "Jen", "Anne"]
time_since_seen = [3, 7, 15, 11]
long_timers = {
friends[i]: time_since_seen[i]
for i in range(len(friends))
# optonal filter:
if time_since_seen[i] > 5
}
It further breaks things down so we can see what we’re stuffing in as a value, what we’re iterating over to do that, and lastly the modifier. The result would be as follows:
>>> long_timers
{'Bob': 7, 'Jen': 15, 'Anne': 11}
Note that Rolf
, whose time_since_seen
was less than 5, was not included in the result because of our filter on that comprehension.
I think list comprehension is pretty nifty.