Disclaimer: Obviously, this should not be used for any practical purpose.
Based on @superb rain's answer, by filtering through gc.get_objects
, we can get the list comprehension under construction:
import gc
def get_first_obj(obj_ids):
for obj in gc.get_objects():
if id(obj) in obj_ids or obj is obj_ids:
continue
return obj
obj_ids = set(id(obj) for obj in gc.get_objects())
xs = [(get_first_obj(obj_ids).append("Evil!"), i)[1] for i in range(5)]
print(xs)
Output:
['Evil!', 0, 'Evil!', 1, 'Evil!', 2, 'Evil!', 3, 'Evil!', 4]
Note that this is not very robust; for instance what would happen when get_first_obj
is not called immediately?
Here, we print out new objects created during the comprehension as follows:
import gc
def print_objs(obj_ids):
for obj in gc.get_objects():
if id(obj) in obj_ids or obj is obj_ids:
continue
print(id(obj), obj)
obj_ids = set(id(obj) for obj in gc.get_objects())
xs = [(print_objs(obj_ids), i)[1] for i in range(5)]
Output:
139842827736960 []
139842827736960 [0]
139842827879264 ('sep', 'end', 'file', 'flush')
139842827736960 [0, 1]
139842827879264 ('sep', 'end', 'file', 'flush')
139842828122560 []
139842832825536 {'Py_Repr': [{...}, [...]]}
139842827736960 [0, 1, 2]
139842827879264 ('sep', 'end', 'file', 'flush')
139842828122560 []
139842832825536 {'Py_Repr': [{...}, [...]]}
139842827736960 [0, 1, 2, 3]
139842827879264 ('sep', 'end', 'file', 'flush')
139842828122560 []
139842832825536 {'Py_Repr': [{...}, [...]]}
It looks like the first item printed is usually the comprehension-produced object.
Interestingly, nothing is printed during a dict comprehension.