2

使用列表推导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)

>>> out_main
[5, 2, 7]

>>> in_main
[4, 1]

我试图保持简单,但作为一个使用示例,main_list可​​以是part_list包含字典键的字典中的值。我需要同时生成两个列表。

4

5 回答 5

6

只要您没有重复的数据和顺序无关紧要。

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

任务完成。

于 2012-04-12T13:50:41.613 回答
5

如果顺序(在 part_list 中)很重要:

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))
于 2012-04-12T13:49:39.297 回答
2

itertools适用于可迭代对象的基于true的解决方案:

>>> 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_mainout_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-12T14:24:50.970 回答
0
in_main = list(set(main_list) & set(part_list))
out_main = list(set(part_list) - set(in_main))
于 2012-04-12T14:10:54.540 回答
0

从谓词列表开始:

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)(当然不是在列表理解中,而是在之前)。

于 2012-04-12T14:43:43.753 回答