相当于filter()的python获取两个输出列表(即列表的分区)


问题内容

假设我有一个列表和一个过滤功能。使用类似

>>> filter(lambda x: x > 10, [1,4,12,7,42])
[12, 42]

我可以得到符合条件的元素。我是否可以使用一个函数来输出两个列表,一个匹配的元素,一个剩余的元素?我可以filter()两次调用该函数,但这有点难看:)

编辑: 元素的顺序应守恒,我可能多次拥有相同的元素。


问题答案:

尝试这个:

def partition(pred, iterable):
    trues = []
    falses = []
    for item in iterable:
        if pred(item):
            trues.append(item)
        else:
            falses.append(item)
    return trues, falses

用法:

>>> trues, falses = partition(lambda x: x > 10, [1,4,12,7,42])
>>> trues
[12, 42]
>>> falses
[1, 4, 7]

itertools配方中还有一个实现建议:

from itertools import filterfalse, tee

def partition(pred, iterable):
    'Use a predicate to partition entries into false entries and true entries'
    # partition(is_odd, range(10)) --> 0 2 4 6 8   and  1 3 5 7 9
    t1, t2 = tee(iterable)
    return filterfalse(pred, t1), filter(pred, t2)

该食谱来自Python 3.x文档。在Python 2.xfilterfalse中称为ifilterfalse