How to Increment a Number in Python: Operators, Functions, and More
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.
Problem Description
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:
1 2 3 | ++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:
1 2 3 4 5 | >>> 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:
1 2 | >>> +++++++++++++++++++i 7 |
Naturally, we’ll have to look elsewhere if we want to increment a number!
Solutions
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:
1 2 | 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:
x
evaluates to 51
evaluates to 15 + 1
evaluates 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:
1 2 | 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 x
).
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:
1 2 | >>> y = x += 1 SyntaxError: invalid syntax |
Contrast this with the typical increment operators in other languages like Java where this is possible:
1 | 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:
1 2 3 | 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:
1 | list(map(operator.add, [ 1 , 1 , 1 ], [ 5 , - 4 , 13 ])) |
Of course, it might be a little cleaner to use the underlying __add__
method:
1 | 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:
1 2 3 | 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:
1 2 | for i in range( 5 ): pass # Do Something! |
Likewise, we could even make our own counter using a generator expression:
1 | counter = (i for i in range( 5 )) |
Then, to generate terms in the sequence, we could continually call next()
:
1 2 3 4 | >>> 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:
1 2 | x = 10 x += - 1 |
Of course, that’s a bit counterintuitive. Instead, we often opt for the decrement operator:
1 | x -= 1 |
Likewise, direct assignment works just as well:
1 | x = x - 1 |
In addition, the functional solution we’ve mentioned can be modified to get the job done:
1 | 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.
Performance
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:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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 timeit
:
1 2 3 4 5 6 7 8 9 | >>> 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:
1 2 3 4 5 6 7 8 9 | >>> 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:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 | >>> 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.
Challenge
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.
As always, I’ll share an answer in the comments. Feel free to share yours as well!
A Little Recap
And with that, we’re all done! Once again, here are all the solutions in one convenient place:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | 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
Published on Web Code Geeks with permission by Jeremy Grifski, partner at our WCG program. See the original article here: How to Increment a Number in Python: Operators, Functions, and More Opinions expressed by Web Code Geeks contributors are their own. |