In the world of programming languages, expressions are an interesting concept that folks tend to implicitly understand but might not be able to define. As a result, I figured I’d take a crack at defining the concept, especially in the context of Python.
Table of Contents
Concept Overview
Broadly speaking, expressions include anything that can be evaluated (i.e., converted to a value). In practice, you will know if you’ve encountered an expression if it can be evaluated using the eval()
function.
Unfortunately, in Python, expressions are not really a meaningful concept because there are so few examples of syntax that are not expressions. For example, you might think that the print statement is not an expression because it doesn’t return anything. However, all functions have a return value, even if not explicitly set.
result = eval('print("I am a humble statement")') # stores None
In fact, even the name of the function itself is an expression:
result = eval("print") # stores the print function
However, there are a few examples of syntax that are strictly statements, and therefore cannot be evaluated. For example, you cannot evaluate a break statement:
result = eval("break") # throws an invalid syntax error
Nor can you evaluate an assignment statement or an import statement:
result = eval("x = 5") # throws an invalid syntax error result = eval("import os") # also throws an invalid syntax error
For a more in depth description of the difference between statements and expressions and their implications, check out this article, though you will have to wade through some Java. Otherwise, let’s get to your questions!
What Are Some Cool Expressions?
Generally, when we talk about expressions, we imagine a chain of operators, such as in an arithmetic expression:
result = 5 + 4 * 7
However, Python has a ton of interesting expressions you might want to use. For example, the idea of a list comprehension comes to mind, which is an expression that creates a list following our demands. For example, here’s a list compression that generates a list of numbers divisible by 5:
# stores [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50] result = [num for num in range(0, 51) if num % 5 == 0]
I’m also a big fan of having the ability to create a lazy list using a generator expression:
result = (num for num in range(0, 51) if num % 5 == 0) # stores generator expression
This might look identical to the list comprehension, but it creates a generator which can be used to produce values one at a time. This is particularly useful if you only need a few values and not every value.
Outside of list comprehensions and generator expressions, there are lambda expressions, which you can use to create inline functions:
result = lambda num: num + 1
The result is a variable that can be used as a function:
result(1) # returns 2 result(5) # returns 6
Certainly, there are more examples of interesting expressions out there, but these should give you a good idea of their breadth.
How Are Statements Different?
From a Python perspective, a statement is syntax that cannot be evaluated using the eval()
function. More broadly, of course, a statement is just any piece of syntax that performs an action. Or more literally, a statement makes changes to the state of the program. Sometimes, you will hear this referred to as a side effect.
For example, an assignment statement adds a variable to the program’s state. Meanwhile, an if statement provides a new possible path through the program.
In practice, the lines between a statement and expression are always blurry, especially in Python. Even functions which only perform an action—like print()
—are still technically expressions because they have a return value. Therefore, print()
is both an expression and a statement, and that goes for any function (or more accurately, any procedure) that has side effect.
That said, being conscious of the difference might help you write better code. By choosing to make a function have no side effects, you are being more clear about it’s purpose. A similar argument can be made for having a function only produce side effects.
However, this is not always practical. For example, you might be aware that lists have a pop()
method. This method is both a statement and expression in the sense that it performs an action (i.e., removing something from a list) but also returns a value (i.e., the item removed). In theory, you could split pop()
into two methods, where pop()
only updates the list while a method like peek()
tells you what’s going to be removed. Though, I think that’s probably unnecessary.
Expressing Yourself
While Python doesn’t have a very meaningful distinction between statements and expressions, I still think it’s helpful to think about the two concepts when you write code. It’s not absolutely necessary that you always try to differentiate the two in your own code, but being cognizant of the difference might help you write code with less bugs.
I’ve seen this confusion firsthand with my students using a divide()
method that both mutates a number but also returns the remainder. When students want to use divide()
for remainder, they suddenly forget about its side effects, leaving the underlying number unknowingly changed.
At any rate, I think that’s enough for today’s concept! I’m not sure how we’ll expand the concept map next, but I am enjoying covering these byte-sized ideas. I think soon we should be able to start building on these concepts to cover even more complex ideas.
In the meantime, check out some of these related articles:
- How to Version Your Python Projects for Pip
- Poetry Is The Best Way to Manage Your Python Projects
- The Haters Guide to Python
Likewise, here are some resources to help you learn more Python (#ad):
- Effective Python: 90 Specific Ways to Write Better Python
- Python Tricks: A Buffet of Awesome Python Features
- Python Programming: An Introduction to Computer Science
Finally, I always have to pitch my list of ways to grow the site. There, you’ll find the Discord and Patreon. Otherwise, take care! I’ll see you next time.
Recent Code Posts
One of the core features of modern programming languages is functions, but did you know Python has them too? Let's take a look!
Python has a cool feature that allows you to overload the operators. Let's talk about what that means and how you might use it!