'11' + '1' is '111'?

M

metal

'11' + '1' == '111' is well known.

but it suprises me '11'+'1' IS '111'.

Why? Obviously they are two differnt object.

Is this special feature of imutable object?
 
C

Chris Rebert

'11' + '1' == '111' is well known.

but it suprises me '11'+'1' IS '111'.

Why? Obviously they are two differnt object.

Is this special feature of imutable object?

It's an implementation detail used to optimize performance. CPython
caches certain small strings and returns the same object when asked
for a string with identical content to one in the cache, thus the
behavior you're observing.

Cheers,
Chris
 
B

Benjamin Kaplan

'11' + '1' == '111' is well known.

but it suprises me '11'+'1' IS '111'.

Why? Obviously they are two differnt object.

Is this special feature of imutable object?

It's an implementation detail of small strings without spaces and
small numbers. You're more likely to reuse those values, so Python
caches them. You shouldn't rely on it. It's not guaranteed to stay the
same between different implementations, or even different versions of
CPython.
 
M

metal

It's an implementation detail used to optimize performance. CPython
caches certain small strings and returns the same object when asked
for a string with identical content to one in the cache, thus the
behavior you're observing.

Cheers,
Chris
--http://blog.rebertia.com

True, '1'*1000 IS NOT '1'*999+'1'.
 
B

Benjamin Peterson

metal said:
'11' + '1' == '111' is well known.

but it suprises me '11'+'1' IS '111'.

Why? Obviously they are two differnt object.

Is this special feature of imutable object?

As other posters have pointed out, CPython does cache some small strings. In
this case, however, it's because '1' + '11' is constant folded.
 
J

John Machin

It's an implementation detail of small strings without spaces and
small numbers. You're more likely to reuse those values, so Python
caches them. You shouldn't rely on it. It's not guaranteed to stay the
same between different implementations, or even different versions of
CPython.

It also relies on the implementation detail that the CPython bytecode
has peephole optimisation applied to it:

| Python 2.6.4 (r264:75708, Oct 26 2009, 08:23:19) [MSC v.1500 32 bit
(Intel)] on win32
| Type "help", "copyright", "credits" or "license" for more
information.
| >>> def foo():
| ... return '11' + '1' is '111'
| ...
| >>> import dis
| >>> dis.dis(foo)
| 2 0 LOAD_CONST 4 ('111')
| 3 LOAD_CONST 3 ('111')
| 6 COMPARE_OP 8 (is)
| 9 RETURN_VALUE
| >>> def bar():
| ... a = '11'
| ... b = '1'
| ... return a + b is '111'
| ...
| >>> dis.dis(bar)
| 2 0 LOAD_CONST 1 ('11')
| 3 STORE_FAST 0 (a)
|
| 3 6 LOAD_CONST 2 ('1')
| 9 STORE_FAST 1 (b)
|
| 4 12 LOAD_FAST 0 (a)
| 15 LOAD_FAST 1 (b)
| 18 BINARY_ADD
| 19 LOAD_CONST 3 ('111')
| 22 COMPARE_OP 8 (is)
| 25 RETURN_VALUE
| >>> foo()
| True
| >>> bar()
| False
| >>>

In general, whether (expression1 is expression2) is true or false is
not useful knowledge when the expressions result in "scalars" like
str, int, float.
 
M

metal

metal <metal29a <at> gmail.com> writes:







As other posters have pointed out, CPython does cache some small strings. In
this case, however, it's because '1' + '11' is constant folded.

You are right. It's not cache, just constant folding, but it does not
propagate further.

a = '1'
a+a is not a+a
 
M

MRAB

Benjamin said:
As other posters have pointed out, CPython does cache some small strings. In
this case, however, it's because '1' + '11' is constant folded.
It's also easy to fool the constant folding:
False
 

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,743
Messages
2,569,478
Members
44,898
Latest member
BlairH7607

Latest Threads

Top