所以这里有一个简单的例子,可能会以其他方式更好地执行。
这是常规的for-loop版本:
lst1 = ['abc', 'abc', 'cde', 'cde']
lst2 = []
for i in lst1:
if i not in lst2:
lst2.append(i)
非工作列表理解近似:
lst2 = [i for i in lst1 if i not in lst2]
# NameError: name 'lst2' is not defined
所以问题是:是否可以访问列表理解所产生的列表,就像它正在制作一样?
答案 0 :(得分:3)
没有
但如果订单很重要,您需要this回答其他问题:
>>> from collections import OrderedDict
>>> list(OrderedDict.fromkeys(['abc', 'abc', 'cde', 'cde']))
['abc', 'cde']
答案 1 :(得分:2)
不,那是不可能的。但你可以这样做:
>>> seen = set()
>>> [x for x in lst1 if x not in seen and not seen.add(x)]
['abc', 'cde']
如果顺序无关紧要,那么只需使用set(lst1)
。
答案 2 :(得分:1)
TL; DR:没有简单的方法来进行递归列表理解。
为什么?这是因为当解释器到达这一行时,它将首先评估操作的右侧(列表理解)并尝试构建列表。构建后,它将影响为lst2
创建的列表。但是,当您尝试构建列表时,您正在调用尚未定义的lst2
。
您可以查看生成的字节码:
>>> def test(lst1):
... lst2 = [i for i in lst1 if i not in lst2]
...
>>> dis.dis(test)
2 0 BUILD_LIST 0
3 LOAD_FAST 0 (lst1)
6 GET_ITER
>> 7 FOR_ITER 24 (to 34) # the list comprehension is converted into a for loop
10 STORE_FAST 1 (i)
13 LOAD_FAST 1 (i)
16 LOAD_FAST 2 (lst2) # try to load lst2, which doesn't exist yet
19 COMPARE_OP 7 (not in)
22 POP_JUMP_IF_FALSE 7
25 LOAD_FAST 1 (i)
28 LIST_APPEND 2
31 JUMP_ABSOLUTE 7
>> 34 STORE_FAST 2 (lst2)
37 LOAD_CONST 0 (None)
40 RETURN_VALUE
解决方案:您要做的是定义一个集合:
>>> lst1 = ['abc', 'abc', 'cde', 'cde']
>>> set(lst1)
set(['cde', 'abc'])
(我希望你对元素的顺序无关紧要:-))如果顺序很重要:
>>> tmp = set() # create a set of already added elements
>>> [x for x in lst1 if x not in tmp and not tmp.add(x)]
['abc', 'cde']
答案 3 :(得分:1)
不,在列表中,lst2
内容[]
为print id(lst2)
lst2 = [ (i,id(lst2)) for i in lst1 if i not in lst2]
print lst2
print id(lst2)
,直到它返回为止:
{{1}}