Consider l = [1, 2, 3, 4, 5] print(l is l[:]) t = (1, 2, 3, 4, 5) print(t is t[:]) print(t[1:] is t[1:]) print('aa'[1:] is 'aa'[1:]) print('aaa'[1:] is 'aaa'[1:]) The result is, somewhat surprisingly, False, True, False, True, False. Additionally, if I create objects of types list, tuple and str with large lengths and then create large numbers of slices [1:] of each, only with str is it efficient in terms of time and memory, even though tuples are also immutable and could, just like strings, be represented without copying the range specified by a slice, just by indexing into the contiguous memory where the data is already stored. Why does CPython behave this way? Is it an implementation thing, or are all implementations required to follow the same choices? Continue reading...