2015-11-29 8 views

risposta

15

No, non esiste una funzione inversa incorporata per filter(), perché è possibile semplicemente invertire . Basta aggiungere not:

positive = filter(lambda v: some_test(v), values) 
negative = filter(lambda v: not some_test(v), values) 

Il modulo itertools ha itertools.ifilterfalse(), che è piuttosto ridondante perché invertendo un test booleano è così semplice. La versione itertools funziona sempre come un generatore.

+2

Il tuo ragionamento non è molto convincente. Il primo caso può essere già scritto 'positivo = filtro (alcuni_test, valori)' quindi ciò che viene chiesto dovrebbe essere almeno tanto semplice come 'negativo = filtro (non (alcuni_test), valori)' –

+0

ATTENZIONE! 'not' è un builtin in python che valuta immediatamente sia' True' o 'False'. Gli oggetti funzione valutano 'False', e il filtro si aspetta una funzione lì, quindi questo ti darà un errore TypeE perché il primo argomento è un booleano. Gli altri lettori sono attenti. – Multihunter

+0

@Multihunter: and 'not' è * non un built-in *. È un operatore. –

7

È possibile farlo con itertools.filterfalse o come Martijn suggerisce, inserire un not da qualche parte all'interno del lambda che si utilizza nel filtro.

5

Un'altra opzione:

from operator import not_ 
compose = lambda f, g: lambda x: f(g(x)) 

... 

ys = filter(compose(not_, predicate), values) 

si può avere una versione pre-laminati di compose() disponibili (per esempio in funzionale o toolz).

0

Da 's commento a Martijn Pieters' Ross Bencina s answer:

tuo ragionamento non è molto convincente. Il primo caso si può già scritto

positive = filter(some_test, values) 

quindi ciò che viene chiesto dovrebbe essere almeno così semplice come

negative = filter(not(some_test), values) 

Io suggerirei di usare una semplice funzione di negazione avvolgitore:

def _not(func): 
    def not_func(*args, **kwargs): 
     return not func(*args, **kwargs) 
    return not_func 

che consente di scrivere la seconda riga come sopra (con il carattere di sottolineatura aggiunto o altra distinzione, poiché l'operatore not non può e probabilmente non dovrebbe essere sovrascritto):

negative = filter(_not(some_test), values)