Skip to content Skip to sidebar Skip to footer

Python: Referring To A List Comprehension In The List Comprehension Itself?

This thought just came to my mind. Say for whatever reason you wanted to get the unique elements of a list via a list comprehension in Python. [i if i in {created_comprehension} el

Solution 1:

I'll assume i in {created_comprehension} was meant to be i not in {created_comprehension}. At least that's what the data suggests.

So here's a fun horrible abuse that I wouldn't trust to always work. Mainly to demonstrate that the argument "it's impossible because it's not yet assigned" is wrong. While the list object indeed isn't assigned yet, it does already exist while it's being built.

>>> import gc
>>> [i if i notin self else0for ids in [set(map(id, gc.get_objects()))]
     for self in [next(o for o in gc.get_objects() if o == [] andid(o) notin ids)]
     for i in [1, 2, 1, 2, 3]]
[1, 2, 0, 0, 3]

This gets the ids of all objects tracked for garbage collection before the new list gets created, and then after it got created, we find it by searching for a newly tracked empty list. Call it self and then you can use it. So the middle two lines are a general recipe. I also successfully used it for this question, but it got closed before I could post.

A nicer version:

>>> [i if i not inselfelse0foroldin [ids()] forselfin [find(old)]
     foriin [1, 2, 1, 2, 3]]
[1, 2, 0, 0, 3]

That used these helper functions:

defids():
    import gc
    returnset(map(id, gc.get_objects()))

deffind(old):
    import gc
    returnnext(o for o in gc.get_objects() if o == [] andid(o) notin old)

Solution 2:

Disclaimer: this is purely speculation on my part, and I don't have data to back it up

I don't think you can refer to a list comprehension as it is being built. Python will first have to create the list, allocate memory or it, and add elements to it, before it binds it to a variable name. Therefore, I think you'll end up with a NameError if you try to refer to the list, while it's being built in a list-comp

You might ultimately, therefore, want a set to hold your uniques, and build your list from there (Oh God! this is hacky):

In [11]: L = [1, 2, 1, 2, 3]

In [12]: s =set(L)

In [13]: answer = [sub[0] for sub in [(i,s.remove(i)) if i in s else (0,0) for i in L]]

In [14]: answer
Out[14]: [1, 2, 0, 0, 3]

In [15]: s
Out[15]: set()

Solution 3:

Disclaimer: this is just an experiment. I compare a list comprehension and a list inside a list comprehension.

I want x to contain elements from [1,2,1,2,3,4,5] only if those elements are in this list comprehension[e for e in range(3,6)] which should be [3,4,5]

x = [i forain [e foreinrange(3,6)] foriin [1,2,1,2,3,4,5] if i == a]

The output is right:

[3, 4, 5]

Post a Comment for "Python: Referring To A List Comprehension In The List Comprehension Itself?"