Why Read this ?
If you ( like me ) are new to python and/or comprehension I hope this short tutorial will get you up to speed. In a nutshell, comprehension is a way to write concise ( short and effective) python code.
Much of comprehension in python deals with how you speak the language and much like your real language, you can say something with a lot of words (verbose) or say a lot with a few words (succinct).
Even if you prefer verbose code ( I sometimes do ), concise code is widely used, so if you want to read others code it pays to learn about it, let’s start with a plain vanilla verbose example so we have something to work with.
""" Here we are simply populating a list """boxODonuts = 
FLAVORS = ['Glaze', 'Chocolate', 'Vanilla', 'Cinnamon']for flavor in FLAVORS:
boxODonuts.append(flavor + ' donut')print(boxODonuts)OUTPUT:
['Glaze donut', 'Chocolate donut', 'Vanilla donut', 'Cinnamon donut']
Let’s now do something to our donuts, like sample all of them
""" creating a temporary list, iterating over a list, doing something to each item
and replacing the original list with the modified elements"""tempBox = 
for donut in boxODonuts:
tempBox.append('Bitten ' + donut)
boxODonuts = tempBoxprint(boxODonuts)['Bitten Glaze donut', 'Bitten Chocolate donut', 'Bitten Vanilla donut', 'Bitten Cinnamon donut']
One last addition to our example is to encapsulate operations into a function, let’s say after sampling the donuts we decide we liked them all and we want to eat half of each, let’s do that :
""" Here we apply a simple function to each element of a list,
add them to a temporary copy and replace the original list"""def eathalf(donut):
return 'Half eaten ' + donuttempBox = 
for donut in boxODonuts:
boxODonuts = tempBoxprint(boxODonuts)['Half eaten Bitten Glaze donut', 'Half eaten Bitten Chocolate donut', 'Half eaten Bitten Vanilla donut', 'Half eaten Bitten Cinnamon donut']
Let’s start with a fresh box o donuts and add sprinkles with map:
""" Applies a function to a list with map """boxODonuts = ['Glaze donut', 'Chocolate donut', 'Vanilla donut', 'Cinnamon donut']def sprinkle(donut):
return 'Sprinkled ' + donut# Note that map returns a map object, we still need to convert it to a list to replace out original box..tempBox = map(sprinkle, boxODonuts)
boxODonuts = list(tempBox)print(boxODonuts)['Sprinkled Glaze donut', 'Sprinkled Chocolate donut', 'Sprinkled Vanilla donut', 'Sprinkled Cinnamon donut']
⚠️ map() has fallen out of use for many cases in favor of comprehension, but since at this point we are building towards understanding comprehension, it is helpful to know about it, there's a lot of code out there that uses it, so it's also good to know, you can read more about it in this Stack Overflow question:List comprehension vs Map
A lambda is an anonymous ( no name ) function that is meant to be a simple drop in, you can have many arguments but only one expression, so that in itself limits what you can do with them.
To understand lambdas, I recommend you start with a regular function and convert it to a lambda, here’s one such example:
""" Comparison of a regular function and a lambda function, note that we are still naming the lambda function for explanatory purposes"""Regular function:def fillDonut(donut):
return 'Creme Filled ' + donutLambda (this one is named though):fillDonut = lambda donut: 'Creme Filled ' + donut
Using a lambda is identical to using a regular function:
""" Using either of the above functions should give you the same result"""Donuts = ['Glaze donut', 'Chocolate donut', 'Vanilla donut', 'Cinnamon donut']tempBox = 
for donut in Donuts:
boxODonuts = tempBoxprint(boxODonuts)['Creme Filled Glaze donut', 'Creme Filled Chocolate donut', 'Creme Filled Vanilla donut', 'Creme Filled Cinnamon donut']
Packing statements and functions
It might seem that we are not really saving words here, but we have all the elements to produce a short and powerful sentence with what we have reviewed, consider the following rewrite of our last case:
""" One sentence replaces a for loop and a function definition """Donuts = ['Glaze donut', 'Chocolate donut', 'Vanilla donut', 'Cinnamon donut']boxOCremeFilledDonuts = list(map(lambda donut: 'Creme Filled ' + donut, Donuts))print(boxODonuts)['Creme Filled Glaze donut', 'Creme Filled Chocolate donut', 'Creme Filled Vanilla donut', 'Creme Filled Cinnamon donut']
⚠️ Most likely you will find and use lambdas with numerical operations (not donuts), for instance something like this:sumTwo = lambda x,y: x + yprint(sumTwo(5,4)) #9
print(sumTwo(2,3)) #5or in conjunction with other built in functions, sorted() and casefold() in this case:flavors = ["Vanilla", "chocolate", "Maple", "Cinnamon", "bacon"]
print(sorted(flavors, key=lambda f: f.casefold()))# ['Bacon', 'Chocolate', 'Cinnamon', 'Maple', 'Vanilla']# without casefold() sorting doesn’t quite work, the lambda iterates over the flavors list and ignores the case, in comparison:print(sorted(flavors))# ['Cinnamon', 'Maple', 'Vanilla', 'bacon', 'chocolate']Try rewriting these into regular functions if you don’t get them at first, and if writing them yourself, consider not overusing them.
And finally there’s comprehension which builds on the preceding concepts to make complex statements even shorter and to some more readable, let’s start with a simple form of list comprehension.
""" Using comprehension to modify and populate a list, same as our first example, we'll compare them in a second"""FLAVORS = ['Glaze', 'Chocolate', 'Vanilla', 'Cinnamon']boxODonuts = [flavor + ' donut' for flavor in FLAVORS]print(boxODonuts)['Glaze donut', 'Chocolate donut', 'Vanilla donut', 'Cinnamon donut']
""" For comparison, here's both """""" Without comprehension: """boxODonuts = 
for flavor in FLAVORS:
boxODonuts.append(flavor + ' donut')""" With comprehension: """boxODonuts = [flavor + ' donut' for flavor in FLAVORS]
As promised, we’ve said a lot with little code, but at the cost of learning how to say it.
Comprehension doesn’t stop there, we can explore more complex forms, here we add a conditional to exclude from our original list:
""" Using comprehension and a conditional, no Cinnamon donuts here """FLAVORS = ['Glaze', 'Chocolate', 'Vanilla', 'Cinnamon']boxODonuts = [flavor + ' donut' for flavor in FLAVORS if flavor != 'Cinnamon']print(boxODonuts)['Glaze donut', 'Chocolate donut', 'Vanilla donut']
An alternative method for using conditionals in comprehension is to put them up front, this way you can use if/else and branch :
""" We ran out of most flavors, we can only make Glaze Donuts,the rest will have to be muffins ( the lesser pastry )"""FLAVORS = ['Glaze', 'Chocolate', 'Vanilla', 'Cinnamon']boxOPastries = [(flavor + ' Donut') if flavor == 'Glaze' else (flavor + ' Muffin' )for flavor in FLAVORS ]print(boxOPastries)['Glaze Donut', 'Chocolate Muffin', 'Vanilla Muffin', 'Cinnamon Muffin']
One last thing worth mentioning before wrapping things up, is that the output of list comprehension can be a complex function, this allows you the flexibility of mixing short and long statements while generating a list:
""" Here we are throwing everything at our donuts, but by separating the function and using comprehension we can save a few words"""FLAVORS = ['Glaze', 'Chocolate', 'Vanilla', 'Cinnamon']def complexDonut(flavor):
cremefilled = flavor + ' creme filled'
sprinkled = cremefilled + ' sprinkled '
donut = sprinkled + 'donut'
return donutboxODonuts = [complexDonut(flavor) for flavor in FLAVORS ]print(boxODonuts)['Glaze creme filled sprinkled donut', 'Chocolate creme filled sprinkled donut', 'Vanilla creme filled sprinkled donut', 'Cinnamon creme filled sprinkled donut']Note: You can also use an outside lambda definition ( inside the list comprehension it's somehow meaningless ).
Parting words :
I hope this short tutorial get’s you up to speed in python comprehension, but this is just the beginning, there’s two things I would like to leave you with:
- When to use comprehension ? A tricky subject, I recommend you start using it in small lists or dictionaries where the functions are clear and you are replacing a for loop, something like this maybe:
""" Make 1000 random flavor donuts """allTheDonuts = [ random.choice(FLAVORS) + ' donut' for i in range(1000)]
Beyond that you should follow your teams style guide ( if working on a team ), or consider going verbose, here’s more on the subject.
When to Use a List Comprehension in Python - Real Python
Python is famous for allowing you to write code that's elegant, easy to write, and almost as easy to read as plain…
2. Where to go next ? We’ve been using lists to understand comprehension, mostly because they are simple, but comprehension also works in Dictionaries, sets and iterables, additionally, some forms of derived comprehension can get complex, ( nested conditionals for instance ), but I believe you have the bases to tackle most complex cases, here’s another introduction you might find useful:
Thanks for reading !