se faccio:Il cortocircuito riduci() di Python?
result = reduce(operator.and_, [False] * 1000)
si fermerà dopo il primo risultato? (Dal False & anything == False
)
Allo stesso modo:
result = reduce(operator.or_, [True] * 1000)
se faccio:Il cortocircuito riduci() di Python?
result = reduce(operator.and_, [False] * 1000)
si fermerà dopo il primo risultato? (Dal False & anything == False
)
Allo stesso modo:
result = reduce(operator.or_, [True] * 1000)
E non lo fa. La tua alternativa in questo caso è any e all.
result = reduce(operator.and_, [False] * 1000)
result = reduce(operator.or_, [True] * 1000)
potranno essere sostituiti da
result = all([False] * 1000)
result = any([True] * 1000)
che fanno corto circuito.
I risultati di temporizzazione mostrano la differenza:
In [1]: import operator
In [2]: timeit result = reduce(operator.and_, [False] * 1000)
10000 loops, best of 3: 113 us per loop
In [3]: timeit result = all([False] * 1000)
100000 loops, best of 3: 5.59 us per loop
In [4]: timeit result = reduce(operator.or_, [True] * 1000)
10000 loops, best of 3: 113 us per loop
In [5]: timeit result = any([True] * 1000)
100000 loops, best of 3: 5.49 us per loop
Non solo ridurre() non corto-circuito, non può possibilmente corto-circuito su tutte le voci ridursi, perché considera solo gli articoli due a un tempo. Inoltre, non ha idea delle condizioni in cui viene utilizzata la funzione cortocircuiti. (Sarebbe un po 'bello se le funzioni potessero avere una proprietà che indica il valore a cui iniziano a corto circuito, che reduce() potrebbe quindi riconoscere e utilizzare, ma non lo fanno)
Ecco perché gli utenti Lisp amano così tanto il Lisp perché tutte le funzioni sono dati, è (in linea di principio) possibile fare questo tipo di rilevamento. – Lucretiel
Potrebbe essere possibile (vedere fate of reduce) che un'alternativa riduce l'implementazione farà un buon lavoro.
Questa idea ha perfettamente funzionato per me per rendere le cose più trasparenti nel design.
def ipairs(seq):
prev = None
for item in seq:
if prev is not None:
yield (prev, item)
prev = item
def iapply(seq, func):
for a, b in ipairs(seq):
yield func(a, b)
def satisfy(seq, cond):
return all(iapply(seq, cond))
def is_uniform(seq):
return satisfy(seq, lambda a, b: a == b)
Come vedete ridurre è rotto in iapply <-ipairs.
Si prega di notare che non è equivalente a
def ireduce(seq, func):
prev = None
for item in seq:
if prev is None:
prev = item
else:
prev = func(prev, item)
return prev
Tenete a mente che la valutazione di corto circuito non è sempre quello che si vuole. "Fissare" ridurre a corto circuito sarebbe un errore per questo motivo. Ad esempio, di recente ho dovuto modificare il mio uso di all() per ridurre() durante l'elaborazione di un elenco di moduli in django: voglio segnalare qualsiasi problema con is_valid(), non solo il primo.
potrebbe usare un argomento di parole chiave per i criteri di cortocircuito, altri builtin fanno: riduci (operator.or, mylist, key = lambda x:: x <0) – LBarret
Hai ragione. 'any()' e 'all()' sembrano essere esattamente ciò di cui ho bisogno (e probabilmente anche più chiaro). Come hai fatto quel tempismo? –
Sto usando 'ipython' e il suo comando' timeit'. Ma Python ha un modulo timeit. Quindi puoi eseguire 'python -mtimeit" result = any ([True] * 10) "' dalla riga di comando per il timing. –