简体   繁体   English

Python:在列表理解本身中引用列表理解?

[英]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.无论出于何种原因,您都想通过 Python 中的列表理解来获取列表的唯一元素。

[i if i in {created_comprehension} else 0 for i in [1, 2, 1, 2, 3]

[1, 2, 0, 0, 3]

I dunno, I don't really have a purpose for this but it'd be cool if it was possible to refer to the comprehension as it's being created.我不知道,我真的没有这个目的,但是如果可以在创建时引用理解,那会很酷。

(eg How to remove duplicate items from a list using list comprehension? is a similar question) (例如, 如何使用列表理解从列表中删除重复项?是一个类似的问题)

I'll assume i in {created_comprehension} was meant to be i not in {created_comprehension} .我会假设i in {created_comprehension}中的意思是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 not in self else 0
     for ids in [set(map(id, gc.get_objects()))]
     for self in [next(o for o in gc.get_objects() if o == [] and id(o) not in 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.这会在新列表创建之前获取所有被垃圾回收跟踪的对象的 id,然后创建新列表,我们通过搜索新跟踪的空列表来找到它。 Call it self and then you can use it.调用它self然后你就可以使用它了。 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 in self else 0
     for old in [ids()] for self in [find(old)]
     for i in [1, 2, 1, 2, 3]]
[1, 2, 0, 0, 3]

That used these helper functions:使用了这些辅助函数:

def ids():
    import gc
    return set(map(id, gc.get_objects()))

def find(old):
    import gc
    return next(o for o in gc.get_objects() if o == [] and id(o) not in old)

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. Python首先必须创建列表,分配内存或它,并向其中添加元素,然后将其绑定到变量名。 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因此,我认为如果您尝试引用该列表,则最终会出现NameError ,而它是在 list-comp 中构建的

You might ultimately, therefore, want a set to hold your uniques, and build your list from there (Oh God! this is hacky):因此,您最终可能需要一个set来保存您的独特之处,并从那里建立您的列表(天哪!这太糟糕了):

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()

Disclaimer: this is just an experiment.免责声明:这只是一个实验。 I compare a list comprehension and a list inside a list comprehension .我比较一个list comprehensionlist一个内部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包含来自[1,2,1,2,3,4,5]元素,仅当这些元素在此list comprehension [e for e in range(3,6)]应该是[3,4,5]

x = [i for a in [e for e in range(3,6)] for i in [1,2,1,2,3,4,5] if i == a]

The output is right:输出是正确的:

[3, 4, 5]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM