semantics of the |= operator

A

akva

Hi All,

what's the exact semantics of the |= operator in python?
It seems that a |= d is not always equivalent to a = a | d

For example let's consider the following code:

def foo(s):
s = s | set([10])

def bar(s):
s |= set([10])

s = set([1,2])

foo(s)
print s # prints set([1, 2])

bar(s)
print s # prints set([1, 2, 10])

So it appears that inside bar function the |= operator modifies the
value of s in place rather than creates a new value.
I'm using Python 2.5

Thanks everybody,
Vitali
 
D

Diez B. Roggisch

akva said:
Hi All,

what's the exact semantics of the |= operator in python?
It seems that a |= d is not always equivalent to a = a | d

For example let's consider the following code:

def foo(s):
s = s | set([10])

def bar(s):
s |= set([10])

s = set([1,2])

foo(s)
print s # prints set([1, 2])

bar(s)
print s # prints set([1, 2, 10])

So it appears that inside bar function the |= operator modifies the
value of s in place rather than creates a new value.

Yes. That's the exact purpose of the in-place operators when they deal with
mutable objects. What else did you expect?

Now of course this behaves different:

def foo(x):
x += 1

y = 100
foo(y)
print y

will result in y still being 100, as the value 101 that is bound to x inside
foo is *not* re-bound to the name y in the outer scope. This is because
numbers (and strings and tuples) are immutables, and thus the operation
won't modify the 100 in place to become 101, instead return a new object.

Diez
 
T

Terry Reedy

akva said:
Hi All,

what's the exact semantics of the |= operator in python?
It seems that a |= d is not always equivalent to a = a | d

The manual explicitly specifies that mutable objects may implement the
operation part of operation-assignments by updating in place -- so that
the object assigned is a mutated version of the original rather than a
new object.

The value equivalency only applies in the namespace in which the
statement appears.
For example let's consider the following code:

def foo(s):
s = s | set([10])

def bar(s):
s |= set([10])

s = set([1,2])

foo(s)
print s # prints set([1, 2])

Put the print inside foo and you will get set([1,2,10]), as with bar.
bar(s)
print s # prints set([1, 2, 10])

So it appears that inside bar function the |= operator modifies the
value of s in place rather than creates a new value.

This has nothing to do with being inside a function.

tjr
 
A

akva

thanks all,
Yes. That's the exact purpose of the in-place operators when they deal with
mutable objects. What else did you expect?

well, frankly I expected a |= b to mean exactly the same as a = a | b
regardless of the object type.
The manual explicitly specifies that mutable objects may implement the
operation part of operation-assignments by updating in place  -- so that
the object assigned is a mutated version of the original rather than a
new object.

could you please refer me a link where this is specified? I couldn't
find it
in python documentation
This has nothing to do with being inside a function.

yes, I know. maybe my example is a bit too verbose. could avoid using
functions.
But you got my main point. I found it somewhat counter-intuitive that
operation-assignments
can modify value in place.

Regards,
Vitali
 
F

Fredrik Lundh

akva said:
could you please refer me a link where this is specified? I couldn't
find it in python documentation

http://docs.python.org/ref/augassign.html

"An augmented assignment expression like x += 1 can be rewritten as x =
x + 1 to achieve a similar, but not exactly equal effect. In the
augmented version, x is only evaluated once. Also, when possible, the
actual operation is performed in-place, meaning that rather than
creating a new object and assigning that to the target, the old object
is modified instead."

</F>
 
P

Peter Pearson

well, frankly I expected a |= b to mean exactly the same as a = a | b
regardless of the object type.

So did I. I'm glad your post called this to my attention; I
recently told my kid exactly that wrong thing.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top