originally published on the Coding Duck blog: www.ccstechme.com/coding-duck-blog
Today's topic? List Comprehensions! The Pythonic way of doing Pythonic things with lists Pythonically.
Okay Jake yeah, Pythonic and such. We get it
But do you? I mean do you really? For instance, did you know that there are not only list comprehensions, but also dict AND set comprehensions?
You know what? Yeah, you probably did. Per the cheeky overuse of "pythonic" above, most who are familiar with the language understand that it values one-liners very highly. A list/dict/set comprehension is, what I feel, the most common of these one-liners. But what is it that they really do? While this post will cover list comprehensions specifically, these same concepts can be applied to other types of comprehensions with some differences. Leave a comment if you'd like a post for each of the other types of comprehensions as well. But seeing as I only have 5 minutes, allow me to answer the question about list comps for you.
umm....was I supposed to type something here...
All kidding aside, a code sample is not entirely necessary to explain comprehensions. Really because there is not that much mystery to them. Basically a comprehension is a wrapper for flow control and conditionals that assigns to a variable.
Now for the sake of posterity, I will provide a code sample that shows you these different methods side by side:
this_string = 'thisstring'
#traditional list building
a_list = []
for i in this_string:
a_list.append(i)
#list_comprehension
b_list = [i for i in this_string]
See the difference? Exactly the same thing is accomplished in both cases: we iterate over a string and append each letter to a list. The difference is we do it in less lines of code.
See the way this works is to, essentially, put the logic of a loop between brackets "[]", which tells the interpreter "hey, I want to make a list out of whatever is in here". But the syntax is a little weird right? Not if you break it down.
Essentially, a for loop's syntax says the following "for each item (i) in this chunk of other items (this_string), perform this action (a_list.append(i))."
A comprehension says this exactly, but more like this: "I want you to perform this action (i) on each of these items (i) in this set of other items (this_string) and store it in a list."
Where most people get thrown off, or don't really think about what is going on under the hood, is the '[i for i.....]' bit. Sometimes I even just type something similar out of reflex. But by saying '[i for i.....]' your are actually saying "keep i as it is each time you see it"
Let me give you some clarification:
this_list = ['t\n', 'h\n','i\n', 's\n', 's\n','t\n','r\n','i\n','n\n','g\n']
b_list = [i.strip() for i in this_list]
In this case, b_list prints out exactly what it did in the first example, but we added the strip() function onto the first i. Had we typed in [i for i in this_list], those newline characters ('\n') would have remained in the new list. Why? Because [i for i.....] means "keep i as it is", whereas [i.strip() for i.....] means "remove the newline characters from 'i' as you go, would you?" If we had specified [i.upper() for i.....], we would have told python "capitalize i as you go, would you?", etc. Basically, the first time you throw down that iterator (i), you're telling Python what to do with it as it builds the list. You could even throw (i) into a function in that place as well:
def silly_function(item_to_do_silly_things_to):
s = f"For that which I say to you sir: {item_to_do_silly_things_to}!!!"
return s
this_list = ['t\n', 'h\n','i\n', 's\n', 's\n','t\n','r\n','i\n','n\n','g\n']
b_list = [silly_function(i) for i in this_list]
This list would now contain the sentence "For that which I say to you sir: t\n!!!" all the way down to "For that which I say to you sir: g\n!!!!", inserting each character in (this_list) into the end of the sentence.
Okay, so we can iterate over things in one line and make a list. What else can list comprehensions do? Pretty much anything you can do in a standard loop actually. We can add in conditionals like "if" statements, use multiple functions, even perform calculations on each item as it goes into the list. I'll be posting a bit more of a deep dive on list comprehensions and their capabilities, limitations, and when you should start hearing alarm bells that maybe a list comprehension just isn't the right choice for that given situation.
Until then, I hope this has cleared up what a list comprehension is and has given you the shallow-end version of what they are useful for. Give them a try. Experiment with them a bit and see if you can replace some for loops in your personal projects. As always, keep coding, keep building, and try not to build another social media site. I mean seriously. I know that they can have 4 employees and no revenue whatsoever and still be bought by Facebook for over a billion dollars. But, I don't even like my own selfies, let alone seeing nothing but selfies of people I don't like or haven't spoken to in 15 years. It's not that I don't care that its your youngest dog's third birthday, its just...no actually it is that. I haven't spoken to you since we were 6 and I have never met your dog. I really do not care its his third birthday.
So if you have been shouldered with the title "Junior", "Newbie", "Intern", "Coffee-Getter", "Probie" (we've all had that PM that still likes NCIS and calls people "Probie". I don't get it either so you're not alone), or any other name that makes you feel small, stupid, or inadequate; toss that title off and approach this career you've pursued as if you can learn anything. My dad always told myself and my brothers this, and I will pass it on to you: Be humble about what you know, and arrogant about what you can learn.. Nothing is beyond you so keep building, keep learning and, as always, the world needs you.
Top comments (4)
Excellent explainer! It's also worth noting that comprehensions are generally faster than
for
/while
loops or usingmap
. The Python interpreter is optimized to recognize comprehensions as a predictable pattern, so doing it the Pythonic way will also give your code a boost :)You beat me to it! I am actually planning a post for next week that discusses the performance differences between Lambdas, Comprehensions, and functions like zip() for data-set creations in Python. I know you already know what the findings of that post will be, but don't spoil it! :D
Oh no! Sorry to jump the gun. I've been really enjoying your Py in 5 posts. I can't wait to see the next one :)
Thanks so much! Little preview, next one is on @decorators :O. Stay tuned. I've got a post on Jinja and web template engines coming before that (Not part of py in 5 series, bit of a deeper dive), but this week it should be up :D