真正itertools
为基础的解决方案,在一个迭代的工作原理:
>>> 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_list改为O(1)查找的集合。
>>> main_set = set(main_list)
>>> in_main = []
>>> out_main = []
>>> for p in part_list:
... (in_main if p in main_set else out_main).append(p)
...
>>> in_main
[4, 1]
>>> out_main
[5, 2, 7]
还有一个有趣的collections.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]})
我觉得这可以用集合来完成 – 2012-04-12 13:48:25
@JakobBowyer main_list值可以从字典中生成。集合是显而易见的解决方案,但寻找一个列表理解或itertools类型的解决方案,同时生成两个列表。 – 2012-04-12 14:02:59