Python列表理解,使用条件语句从列表创建长度不等的列表

Python列表理解,使用条件语句从列表创建长度不等的列表,python,generator,list-comprehension,Python,Generator,List Comprehension,使用列表理解、itertools或类似函数,是否可以根据条件列表从列表中创建两个不相等的列表?以下是一个例子: main_list = [6, 3, 4, 0, 9, 1] part_list = [4, 5, 1, 2, 7] in_main = [] out_main = [] for p in part_list: if p not in main_list: out_main.append(p) else: in_main.append(p) print o

使用列表理解、itertools或类似函数,是否可以根据条件列表从列表中创建两个不相等的列表?以下是一个例子:

main_list = [6, 3, 4, 0, 9, 1]
part_list = [4, 5, 1, 2, 7]

in_main = []
out_main = []

for p in part_list:
  if p not in main_list:
    out_main.append(p)
  else:
    in_main.append(p)

print out_main
print in_main

>>> [5, 2, 7]
>>> [4, 1]
尽量保持简单,但作为用法示例,主列表可以是字典中的值,而部分列表包含字典键。需要同时生成两个列表。Hth.

如果订单(在零件清单内)很重要:

out_main = [p for p in part_list if p not in main_list]
in_main = [p for p in part_list if p in main_list]
否则:

out_main = list(set(part_list) - set(main_list))
in_main = list(set(part_list) & set(main_list))

只要你没有重复的数据&顺序无关紧要

main_set = set([6, 3, 4, 0, 9, 1])
part_set = set([4, 5, 1, 2, 7])

out_main = part_set - main_set
in_main = part_set & main_set

工作完成。

一个真正的基于itertools的解决方案,可在iterable上运行:

in_main = list(set(main_list) & set(part_list))
out_main = list(set(part_list) - set(in_main))
>>> part_iter = iter(part_list)
>>> part_in, part_out = itertools.tee(part_iter)
>>> in_main = (p for p in part_in if p in main_list)
>>> out_main = (p for p in part_out if p not in main_list)
从这些列表中列出会破坏使用迭代器的目的,但结果如下:

>>> list(in_main)
[4, 1]
>>> list(out_main)
[5, 2, 7]
这具有从另一个延迟生成的序列延迟生成
in_main
out_main
的优点。唯一的问题是,如果您先遍历一个,则
tee
必须缓存一组数据,直到另一个迭代器使用它。因此,只有在大致同时遍历它们时,这才是真正有用的。否则,您不妨自己使用辅助存储器

还有一个有趣的基于三元运算符的解决方案。(您可以将其压缩为列表理解,但这是错误的。)我将main_列表更改为一个用于O(1)查找的集合

还有一个有趣的
集合。defaultdict
方法:

>>> import collections
>>> in_out = collections.defaultdict(list)
>>> for p in part_list:
...     in_out[p in main_list].append(p)
... 
>>> in_out
defaultdict(<type 'list'>, {False: [5, 2, 7], True: [4, 1]})
导入集合 >>>in_out=collections.defaultdict(列表) >>>对于零件清单中的p: ... 输入输出[p在主列表中].append(p) ... >>>进进出出 defaultdict(,{False:[5,2,7],True:[4,1]})
从谓词列表开始:

test_func = [part_list.__contains__, lambda x: not part_list.__contains__(x)]
# Basically, each of the predicates is a function that returns a True/False value     
# (or similar) according to a certain condition.
# Here, you wanted to test set intersection; but you could have more predicates.

print [filter(func, main_list) for func in test_func]
然后您就有了“一行程序”,但通过维护谓词列表,您会有一些开销


正如在其他答案中所说,您可以使用
set(main_list)
来加快查找速度(当然不是在列表理解中,而是在之前)。

我觉得这可以用sets@JakobBowyer可以从字典生成主列表值。集合是显而易见的解决方案,但要寻找同时生成两个列表的单一列表理解或itertools类型解决方案。只要顺序不重要。变量要命名为
main\u set
part\u set
:(我发誓我先写了答案集:第二个答案是P+1,但不确定itertools的答案。似乎这已经结束了,它还包括压缩最终结果,并将
None
in_main
out_main
@jamylak中过滤出来,啊,这只是为了显示General的内容。)议员们。我要换一种说法……我喜欢
defaultdict
,似乎比拥有两个变量要好:在defaultdict解决方案中,它是如何自动创建“虚假”列表的?我完全可以接受否决票,但你能解释一下原因吗?谢谢!我支持你,因为我讨厌人们在没有反馈的情况下否决票。
test_func = [part_list.__contains__, lambda x: not part_list.__contains__(x)]
# Basically, each of the predicates is a function that returns a True/False value     
# (or similar) according to a certain condition.
# Here, you wanted to test set intersection; but you could have more predicates.

print [filter(func, main_list) for func in test_func]