The behavior of Python’s increment and decrement operations

Problem

I noticed that a variable can have a pre-increment/decrement operator (like ++count). It builds, but it makes no changes to the variable’s value!

In Python, how do the pre-increment/decrement operators (++/–) behave?

Why does Python behave differently than C/C++ when it comes to these operators?

Solution #1

++ isn’t a valid operator. There are two + operators. The identity operator, which performs nothing, is the + operator. (Clarification: the + and – unary operators only work on integers; I assume that a hypothetical ++ operator would not work on strings.)

``````++count
``````

Parses as

``````+(+count)
``````

Which translates to

``````count
``````

To accomplish your goal, you must utilize the slightly lengthier += operator:

``````count += 1
``````

For uniformity and simplicity, I believe the ++ and — operators were removed. I’m not sure what Guido van Rossum used to justify his choice, but here are a few possibilities:

Solution #2

There are no before and post increment operators in Python.

In Python, integers can’t be changed. That is, you are unable to alter them. This is due to the fact that integer objects can be utilized under a variety of names. Consider the following:

``````>>> b = 5
>>> a = 5
>>> id(a)
162334512
>>> id(b)
162334512
>>> a is b
True
``````

The objects a and b are actually the same. If you increased a, you increased b as well. That’s not what you’re looking for. As a result, you’ll have to reassign. As an example:

``````b = b + 1
``````

Many Python writers wanted an increment operator, but that operator would appear to increment the object while actually reassigning it. Because the -= and += operators are shorter than b = b + 1 while still being clearer and more flexible than b++, most users will increment with:

``````b += 1
``````

This will change the value of b to b+1. That is not an increment operator because it reassigns b rather than incrementing it.

In short, Python behaves differently in this situation because it is not C, and it is not a low-level wrapper around machine code, but a high-level dynamic language, where increments don’t make sense and aren’t as necessary as they are in C, where you use them every time you have a loop, for example.

Solution #3

While the other solutions are right in that they demonstrate what a simple + normally does (that is, leave the number alone if it is one), they are incomplete in that they do not explain what happens.

+x evaluates to x. pos (), while ++x evaluates to x. pos ().

I can picture a VERY odd class structure like this: (Kids, don’t do this at home!)

``````class ValueKeeper(object):
def __init__(self, value): self.value = value
def __str__(self): return str(self.value)

class A(ValueKeeper):
def __pos__(self):
print 'called A.__pos__'
return B(self.value - 3)

class B(ValueKeeper):
def __pos__(self):
print 'called B.__pos__'
return A(self.value + 19)

x = A(430)
print x, type(x)
print +x, type(+x)
print ++x, type(++x)
print +++x, type(+++x)
``````

Solution #4

Unary increment/decrement operators (–/++) are not available in Python. Instead, use to increase a value.

``````a += 1
``````

But proceed with caution. If you’re coming from C, you’ll see that this isn’t the case with Python. Python does not use “variables” in the same sense as C; instead, it utilizes names and objects, and ints are immutable in Python.

So, let’s pretend you do.

``````a = 1
``````

In Python, this implies creating an object of type int with the value 1 and binding the name a to it. The term a corresponds to the object, which is an instance of int with value 1. The name a and the thing it refers to are two different things.

Let’s pretend you do.

``````a += 1
``````

Because ints are immutable, the following happens:

Try it for yourself:

``````a = 1
print(hex(id(a)))
a += 1
print(hex(id(a)))
``````

Solution #5

These operators are not available in Python, but if you really need them, you can write a function that performs the same function.

``````def PreIncrement(name, local={}):
#Equivalent to ++name
if name in local:
local[name]+=1
return local[name]
globals()[name]+=1
return globals()[name]

def PostIncrement(name, local={}):
#Equivalent to name++
if name in local:
local[name]+=1
return local[name]-1
globals()[name]+=1
return globals()[name]-1
``````

Usage:

``````x = 1
y = PreIncrement('x') #y and x are both 2
a = 1
b = PostIncrement('a') #b is 1 and a is 2
``````

If you want to update a local variable, you must add locals() as a second argument to a function; otherwise, it will try to change a global variable.

``````x = 1
def test():
x = 10
y = PreIncrement('x') #y will be 2, local x will be still 10 and global x will be changed to 2
z = PreIncrement('x', locals()) #z will be 11, local x will be 11 and global x will be unaltered
test()
``````

You can also accomplish the following using these functions:

``````x = 1
print(PreIncrement('x'))   #print(x+=1) is illegal!
``````

However, the following technique, in my opinion, is much clearer:

``````x = 1
x+=1
print(x)
``````

Decrement operators:

``````def PreDecrement(name, local={}):
#Equivalent to --name
if name in local:
local[name]-=1
return local[name]
globals()[name]-=1
return globals()[name]

def PostDecrement(name, local={}):
#Equivalent to name--
if name in local:
local[name]-=1
return local[name]+1
globals()[name]-=1
return globals()[name]+1
``````

These routines were utilized in my javascript-to-python package.