Every once in awhile, I like to revisit Python fundamentals to see if I can learn anything new about the language. This time around I thought it would be fun to look at a few different ways to increment a number in Python.
As it turns out, there two straightforward ways to increment a number in Python. First, we could use direct assignment: `x = x + 1`. Alternatively, we could use the condensed increment operator syntax: `x += 1`. In addition, there are a few less conventional options like using the
add method of the
operator module or using generator expressions. Feel free to dig in below to learn more.
Table of Contents
When solving programming problems, one very common operation is adding a fixed value to a number. We call this operation increment, and it’s useful in many contexts. For instance, we might want to use a number as a counter, so we can perform a fixed number of operations. In that case, we’d probably start from zero and add one until our condition is met (e.g.
i < 10).
Of course, how you actually accomplish an increment varies by language. For example, in C-style languages, there are often direct increment operators (though be careful how you use them):
++i i++ i += 1
Unfortunately, some of these options above just don’t work in Python. For instance, both the pre-increment (i.e.
++i) and post-increment (i.e.
i++) operators fail in Python:
>>> i = 7 >>> i++ SyntaxError: invalid syntax >>> ++i 7
With the post-increment operator, we see that we get a blatant SyntaxError. In other words, it’s straight up invalid. Meanwhile, the pre-increment operator executes but nothing actually happens. That’s because the unary plus operator in Python does nothing for numbers. In fact, we could put as many pluses as we want:
>>> +++++++++++++++++++i 7
As far as Python is concerned, I understand why they neglected to include the pre-increment and post-increment syntax. For one, Python likes to have “only one way to do something” according to the Zen of Python:
>>> import this The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you're Dutch. Now is better than never. Although never is often better than *right* now. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea -- let's do more of those!
Similarly, the pre-increment and post-increment operators are often ill-defined as they function as both expressions and statements. Naturally, we’ll have to look elsewhere if we want to increment a number!
Fortunately, there are a few ways to increment a value in Python. Otherwise, why would this article exist? At any rate, let’s dig in!
Increment a Number With Assignment
One of the nice things about numbers in Python is that they’re immutable—meaning they cannot be changed. Otherwise, we’d have to deal with pesky issues like aliasing. If you’re interested in learning about the effects of aliasing, I have another article which talks about the risks of copying mutable data types.
At any rate, since Python numbers are immutable, we can use them in arithmetic and assign their value back with ease:
x = 5 x = x + 1
Here, we have defined a variable,
x, which stores the value 5. In the next line, we take
x and add 1 to it. Then, we store the result back into
x. As a result,
x stores 6.
As someone who teaches a lot of introductory programming classes, I find that students are often bothered by this syntax the first time. After all, most students are familiar with the
= from math, so they haven’t made the connection that
= is really the assignment operator—which makes the statement `x = x + 1` very much legal.
If this syntax bothers you, my advice is to ignore the left-hand side (i.e. `x =`). Instead, focus on what is happening on the right-hand side of the statement (i.e.
x + 1). This portion of the statement is called an expression, and we can have literally anything there as long as it evaluates to some value. In this case, we can evaluate the expression directly in three steps:
xevaluates to 5
1evaluates to 1
5 + 1evaluates to 6
At this point, the result is stored back into
x which overwrites its previous value, 5.
If this breakdown of statements and expressions sounds interesting to you, I recommend checking out my article which dives into this topic a bit further. Otherwise, we’ll look at the next solution.
Increment a Number Using an Operator
Like most programming languages, Python has a way of including syntactic sugar for scenarios like increment. That said, there is only one true increment operator:
+=. To use it, we’ll need to rework our code from before:
x = 5 x += 1
As we can probably imagine, this statement works exactly like the line from the previous section. However, we’ve removed some redundant code (i.e. the additional
One of the nice things about this operator is that it creates a standalone statement. In other words, it cannot be embedded in other contexts:
>>> y = x += 1 SyntaxError: invalid syntax
Contrast this with the typical increment operators in other languages like Java where this is possible:
x = x++
Any idea what this does? Answer: absolutely nothing. In this example,
x is incremented. Then, its previous value is returned, and the result is overwritten. In other words,
x stays the same. If that sound wacky, I wrote a whole article about the behavior. It’s one of the reasons I’m glad the syntax never made its way to Python.
Increment a Number Using a Function
One thing I find interesting about Python is the plethora of functional language features it has. For example, in addition to all of the explicit operators, Python includes a set of functional overloads. As a result, we could increment a number without ever using an arithmetic operator:
import operator x = 5 x = operator.add(x, 1)
The advantage of using a function over the direct operator is scalability. For example, we may find that we want to increment an entire list of values. In that case, the
add function does just the trick:
list(map(operator.add, [1, 1, 1], [5, -4, 13]))
Of course, it might be a little cleaner to use the underlying
list(map(1 .__add__, [5, -4, 13])) # the space is important
That said, this solution is probably the most ridiculous for the standard case.
Increment a Number Implicitly
Sometimes it doesn’t make sense to manually increment a number. After all, in our problem description, we talked about using a number as a counter in a loop. Most of the time, however, we try to avoid explicit counters by using iterators. For example, if we wanted to loop over characters in a string, we could write the following:
my_string = "Bob" for character in my_string: pass # Do Something!
Notice how we didn’t have to explicitly increment a counter. Since strings are iterable, all of that is taken care of for us.
Of course, sometimes we still want to do some counting. After all, we might want to perform an action exactly 5 times. In that case, we can use a range:
for i in range(5): pass # Do Something!
Likewise, we could even make our own counter using a generator expression:
counter = (i for i in range(5))
Then, to generate terms in the sequence, we could continually call
>>> next(counter) 0 >>> next(counter) 1
All of these options perform an increment operation implicitly. Depending on your needs, that might make more sense. Of course, that’s up to you to decide.
Bonus: Decrement a Number
I’d hate to go through an entire article talking about incrementing numbers without ever bringing up the compliment operation: decrement. Without introducing any additional syntax, we can decrement a number with ease:
x = 10 x += -1
Of course, that’s a bit counterintuitive. Instead, we often opt for the decrement operator:
x -= 1
Likewise, direct assignment works just as well:
x = x - 1
In addition, the functional solution we’ve mentioned can be modified to get the job done:
x = operator.sub(x, 1)
Of course, as we’ve already mentioned, it’s probably a bit excessive to do anything like this. Instead, stick to the decrement operator.
As always, I like to take a look at the various solutions and compare them in terms of performance. To do that, we’ll need to put each solution in its own string:
setup = """ import operator """ assignment = """ x = 0 x = x + 1 """ increment = """ x = 0 x += 1 """ function = """ x = 0 x = operator.add(x, 1) """ generator = """ x = (i for i in range(5)) next(x) """
Then, to test these options, we’ll need to run them with
>>> import timeit >>> min(timeit.repeat(setup=setup, stmt=assignment)) 0.03538969999999608 >>> min(timeit.repeat(setup=setup, stmt=increment)) 0.03586820000001012 >>> min(timeit.repeat(setup=setup, stmt=function)) 0.09383009999999103 >>> min(timeit.repeat(setup=setup, stmt=generator)) 0.6202383999999768
Naturally, the core operators get the job done the fastest, but I don’t love the generator test. As a result, I decided to rewrite it so the setup string includes the generator up to a very large value:
>>> setup = """ import operator x = (i for i in range(100000000)) """ >>> generator = """ next(x) """ >>> min(timeit.repeat(setup=setup, stmt=generator)) 0.11321939999999131
Now, that’s a bit more respectable. Of course, I’m wondering if including
x in the setup string will change the original tests as well:
>>> setup = """ import operator x = 0 """ >>> assignment = """ x = x + 1 """ >>> increment = """ x += 1 """ >>> function = """ x = operator.add(x, 1) """ >>> min(timeit.repeat(setup=setup, stmt=assignment)) 0.05624840000001541 >>> min(timeit.repeat(setup=setup, stmt=increment)) 0.061655099999995855 >>> min(timeit.repeat(setup=setup, stmt=function)) 0.12224320000001399
In either case, it looks like the direct assignment or increment operators are the best choice. To put this into context, I ran all tests using Python 3.7.3 on a Windows 10 machine.
When I was thinking about a good challenge, I had a hard time coming up with an idea. After all, there are a lot of different contexts where incrementing a variable could be useful, but it’s not exactly a skill we can build on.
As a result, I thought it might be more fun to come up with a complex increment function which has various conditions. For example, here are some of the conditions:
- If the current number is odd, add 1
- If the current number is even, add 3
- If the current number is divisible by 5, add 5
As an added wrinkle, each number will need to be checked for all three criteria. For example, the number 15 is both odd and divisible by 5. As a result, the next number should be 21 (i.e. 15 + 5 + 1). Likewise, the number 12 will only meet the even criteria, so the next number will be 15.
Here’s an example of the expected behavior:
inc(7) # returns 8 inc(4) # returns 7 inc(5) # returns 11
A Little Recap
And with that, we’re all done! Once again, here are all the solutions in one convenient place:
x = 0 # Increment by one with assignment x = x + 1 # Increment by one with the increment operator x += 1 # Increment by one with a function import operator x = operator.add(x, 1) # Increment by one implicitly on an iterable my_string = "Bob" for character in my_string: pass # Do Something! # Increment by one implicitly using range for i in range(5): pass # Do Something! # Increment by one implicitly using a generator expression counter = (i for i in range(5)) next(counter) # Decrement by one with assignment x = x - 1 # Decrement by one with the decrement operator x -= 1 # Decrement by one with a function x = operator.sub(x, 1)
If you liked this sort of thing, there are tons of ways to help grow the site. Of course, one quick way is to continue browsing:
- Rock Paper Scissors Using Modular Arithmetic
- How to Write a Loop in Python
- How to Comment Code in Python
While you’re here, check out some of the resources on Amazon (ad):
Otherwise, thanks for stopping by! Come back soon.
Magic numbers are numerical constants that have no clear meaning in the code and therefore make code harder to read. Anything that makes code harder to read is something we can use to obfuscate our...
Type hinting is a nice tool that dynamic typing languages employ to make code more readable. As you can probably imagine, readability is not the goal with obfuscating code, so we ought to get rid of...