0

Doing some basic experiments about Python array slicing. Why the same level has the same id(address), but the array value is different. Is the the mechanism of Python slicing, or it just how id() works?

a = [1, 2, 3, 4, 5, 6]
def test2(a, level):
    if not a: return
    mid = len(a) // 2
    print(level, a, id(a))

    if len(a) > 1:
        test2(a[:mid], level + 1)
        test2(a[mid:], level + 1)
test2(a, 0)


## Result:
# 0 [1, 2, 3, 4, 5, 6] 4565360520
# 1 [1, 2, 3] 4565360456
# 2 [1] 4566307656
# 2 [2, 3] 4566307656
# 3 [2] 4566307592
# 3 [3] 4566307592
# 1 [4, 5, 6] 4565360456
# 2 [4] 4566307656
# 2 [5, 6] 4566307656
# 3 [5] 4566307592
# 3 [6] 4566307592
## Same level has same id??

Then when I append the [level, a, id(a)] in to a stack then print it out. The same level has different id now. No matter when I print it out in the function, or store in the stack, then print it out one by one.

a = [1, 2, 3, 4, 5, 6]
stack = []
def test2(a, level):
    if not a: return
    mid = len(a) // 2
    print(level, a, id(a))
    stack.append([level, a, id(a)])
    if len(a) > 1:
        test2(a[:mid], level + 1)
        test2(a[mid:], level + 1)
test2(a, 0)

print("-----------------")
stack = sorted(stack)
for i in stack:
    print(i)

'''
0 [1, 2, 3, 4, 5, 6] 4393918344
1 [1, 2, 3] 4394865352
2 [1] 4394510088
2 [2, 3] 4394865608
3 [2] 4394867592
3 [3] 4394867656
1 [4, 5, 6] 4394867912
2 [4] 4394868040
2 [5, 6] 4394868168
3 [5] 4394867720
3 [6] 4394868360
-----------------
[0, [1, 2, 3, 4, 5, 6], 4393918344]
[1, [1, 2, 3], 4394865352]
[1, [4, 5, 6], 4394867912]
[2, [1], 4394510088]
[2, [2, 3], 4394865608]
[2, [4], 4394868040]
[2, [5, 6], 4394868168]
[3, [2], 4394867592]
[3, [3], 4394867656]
[3, [5], 4394867720]
[3, [6], 4394868360]
'''
wjandrea
  • 28,235
  • 9
  • 60
  • 81
Fu Hong
  • 9
  • 4
  • You're using CPython, right? `id()` is implementation-specific. – wjandrea May 27 '21 at 02:02
  • 1
    In the version of your code where you don't save all of the slices, the two slices at the same level *don't exist in memory at the same time* (`a[:mid]` goes out of scope and is garbage-collected before `a[mid:]` comes into existence). It's therefore entirely possible (although certainly not guaranteed) that the first one's ID gets reused for the second one. – jasonharper May 27 '21 at 02:07
  • @jason Could you post that as an answer please? I would upvote. The only thing I could think to add is a quote from the documentation where it says the id number isn't guaranteed to be anything in particular. – wjandrea May 27 '21 at 02:21
  • whoops - got my negations mixed up in my previous comment. ID values are only guaranteed to be distinct for objects with *overlapping* lifetimes; two objects with *non-overlapping* lifetimes may share an ID. – user2357112 May 27 '21 at 03:35

0 Answers0