String slicing in Python

I was tinkering with string slicing in Python, and this is the code I came up with:

s = 'a string'
print(id(s[2:]), id(s[4:]))
print(id(s[2:])==id(s[4:]))
print(s[2:] is s[4:])
print(s[2:] is s[4:])

The following are the outcomes of the code:

439651916 439659216
True
False
False

My concern is how those string slices are maintained in memory, why do various slices of a string have the same id, and why do they produce ‘False’ when compared using the ‘is’ keyword with the same id?

You may find that the question on ‘memory’ is addressed here.

As for the last two lines of your code (which are the same?)

print(s[2:] is s[4:])

If you print(s[2:], s[4:]), you’ll see

string ring

… which are clearly different, and as such print(s[2:] is s[4:]) will return False

1 Like

The short version: this has nothing to do with slices.

In the code print(id(s[2:]), id(s[4:])), Python is free to compute one id value, throw away the corresponding slice (because there is nothing else that can use it), create the other slice, and find its id value.

id values, in the reference implementation, correspond to the memory addresses of the objects. Since the first slice was thrown away, it’s perfectly possible (and likely, with how the memory management is implemented) for the second slice to be created in the same place in memory, so it will have the same id value.

Similarly, the code print(id(s[2:])==id(s[4:])) only compares the id results. The slices can be thrown away immediately once the id is calculated, due to the reference-counting garbage collection. When the == is evaluated, the slices are already gone.

In the code print(s[2:] is s[4:]) however, the slices themselves are compared using is. That means they both have to exist in order for is to compare them. If two objects exist at the same time, they have to be stored in separate places in memory.

2 Likes

Thank you so much for your help