使用python list comprehension创建具有唯一值的列表if if子句不起作用

H D*_*cet 0 python list-comprehension python-2.7

我被要求在第三个列表中比较2列表和文件管理器的唯一值.我必须确保第三个列表只包含唯一值,不包含双精度值.

以下代码有效:

import os, random

def makerange(number):
    lijst = [random.randint(1,number) for item in
    range(1,random.randint(2,number))]
    return lijst

a = makerange(20)
b = makerange(20)
c = set()

for item in a:
  if item in b and item not in c:
      c.add(item)
Run Code Online (Sandbox Code Playgroud)

我试图将for循环重写为python列表理解.

c = [ item for item in a if (item in b) & (item not in c)]
Run Code Online (Sandbox Code Playgroud)

但是这个列表理解不起作用?有什么建议为什么这不起作用?我应该如何用列表理解来写这个.

Mar*_*ers 5

您的代码无法工作,因为您无法参考c,因为在理解完成之前它不会存在.

您还使用了错误的运算符; 你需要使用and,而不是&; 后者是按位操作,而不是布尔逻辑AND.它碰巧在这里给你相同的结果,但那只是运气.

以下工作,使用集合理解来生成唯一值:

c = {item for item in a if item in b}
Run Code Online (Sandbox Code Playgroud)

或者,如果您必须使用列表推导,请使用单独的集来跟踪您已处理的值; 从如何在保留顺序的同时从列表中删除重复项的技巧:

seen = set()
c = [item for item in a if item in b and not (item in seen or seen.add(item))]
Run Code Online (Sandbox Code Playgroud)

但你也可以使用一个设置操作,在你的情况下交叉:

c = set(a).intersection(b)
Run Code Online (Sandbox Code Playgroud)

或使用&运算符,该运算符为集合重载以产生交集:

c = set(a) & set(b)
Run Code Online (Sandbox Code Playgroud)

演示(使用非随机值使其更容易重现):

>>> a = [17, 8, 19, 17, 17, 4, 8, 17, 6, 19, 18, 11, 15, 8]
>>> b = [8, 9, 16, 7, 16, 14, 3, 19, 1, 17, 8, 11]
>>> {item for item in a if item in b and item not in c}
set([8, 17, 19, 11])
>>> set(a) & set(b)
set([8, 17, 11, 19])
>>> seen = set()
>>> [item for item in a if item in b and not (item in seen or seen.add(item))]
[17, 8, 19, 11]
Run Code Online (Sandbox Code Playgroud)