-1
a = a[0] = [['Is this information lost?']]

print(a)

Is there any way to gain the string again?
If not, how is this memory-wise handled?

Raumschifffan
  • 360
  • 2
  • 13
  • 3
    Your question is extremely vague. Please edit and add more information on what you are asking. – blackbrandt Dec 06 '21 at 16:11
  • 1
    I didn't check, but `a` has to be defined to something beforehand. Otherwise `a[0]` can't be executed – Alexey S. Larionov Dec 06 '21 at 16:12
  • 4
    @AlexeyLarionov you should check. I'm not actually sure how it works, but it seems to create some kind of circular list. – Samwise Dec 06 '21 at 16:13
  • 1
    @Samwise Seems like a circular list indeed, `id(a[0][0][0][0][0])` returns the same as `id(a)` – Alexey S. Larionov Dec 06 '21 at 16:16
  • @AlexeyLarionov actually not... when the given code is pasted into a Python interpreter, it gets `[[...]]` as output. See [What do ellipsis mean in a list](https://stackoverflow.com/questions/17160162/what-do-ellipsis-mean-in-a-list). – blackbrandt Dec 06 '21 at 16:17
  • I guess some kind of infinite nested list is created with the same first element as its outer or inner list. – Shivang Gupta Dec 06 '21 at 16:18

2 Answers2

2

This example is a bit more illustrative of what's going on:

>>> b = [1, 2]
>>> print(id(b))
22918532837512
>>> a = a[0] = b
>>> print(a)
[[...], 2]
>>> print(id(a))
22918532837512
>>> print(id(a[0]))
22918532837512
>>> print(b)
[[...], 2]
>>> print(id(b))
22918532837512

It is important to understand here that = is not formally an operator in Python, but rather a delimiter, part of the syntax for assignment statements. In Python, unlike in C or C++, assignments are not expressions. Multi-assignment statements such as x = y = z are directly accommodated by assignment-statement syntax, not as a consequence of using a single assignment as an expression. A multi-assignment specifies that the value(s) being assigned should be assigned to each target (list), so that x = y = z is equivalent to

x, y = z, z

Except that z is evaluated only once. Python does not define the order in which the targets are assigned, but CPython does it left-to-right, so that the above works about the same as

x = z
y = z

except, again, for the multiple evaluation of z.

And with that, we can understand the original statement. This:

a = a[0] = [['Is this information lost?']]

works like

temp = [['Is this information lost?']]
a = temp
a[0] = temp
del temp

, except that it does not involve a temporary name binding for the target list. Indeed, it should be clear that the previous is also equivalent to this, which is how I imagine most people would write it:

a = [['Is this information lost?']]
a[0] = a

Thus, to answer the original question, the string 'Is this information lost?' was never accessible other than via the list, so the assignment to a[0] leaves no name binding through which the string can be reached. The string is indeed lost at that point, in that sense. Python will continue to track it, however, until it is garbage collected.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
1

As far as I can tell, a is a circular structure -- a list whose one and only element is itself.

>>> len(a)
1
>>> a
[[...]]
>>> len(a[0])
1
>>> a[0]
[[...]]

There is no longer any reference to the string, and hence no way to recover it from the Python interpreter. It should also therefore have been garbage-collected and no longer be in memory (although this is not guaranteed, and it may still be cached but inaccessible).

Samwise
  • 68,105
  • 3
  • 30
  • 44