Di list
Innanzitutto un punto molto importante, dal quale tutto seguirà (spero).
In Python ordinario, list
non è speciale in alcun modo (tranne che per avere una sintassi carina per la costruzione, che è principalmente un incidente storico). Una volta [3,2,6]
creato un elenco , è a tutti gli effetti solo un normale oggetto Python, come un numero 3
, un set {3,7}
o una funzione lambda x: x+5
.
(Sì, supporta la modifica dei suoi elementi e supporta l'iterazione e molte altre cose, ma è proprio quello che è un tipo: supporta alcune operazioni, mentre non supporta altre. Int supporta l'innalzamento a un potere, ma questo non rendilo molto speciale - è proprio quello che è un int. lambda supporta la chiamata, ma questo non lo rende molto speciale - questo è ciò che Lambda è, dopo tutto :).
Di and
and
non è un operatore (puoi chiamarlo "operatore", ma puoi anche chiamare "per" un operatore :). Gli operatori in Python sono metodi (implementati attraverso) chiamati su oggetti di qualche tipo, generalmente scritti come parte di quel tipo. Non c'è modo per un metodo di tenere una valutazione di alcuni dei suoi operandi, ma and
può (e deve) farlo.
La conseguenza di ciò è che and
non può essere sovraccaricato, proprio come for
non può essere sovraccaricato. È completamente generale e comunica attraverso un protocollo specificato. Quello che puoi fare è personalizzare la tua parte del protocollo, ma ciò non significa che puoi modificare and
completamente il comportamento . Il protocollo è:
Immagina Python che interpreta "aeb" (questo non accade letteralmente in questo modo, ma aiuta a capire). Quando si tratta di "e", guarda l'oggetto che ha appena valutato (a), e gli chiede: sei vero? ( NON : lo sei True
?) Se sei un autore di una classe, puoi personalizzare questa risposta. Se la a
risposta "no", and
(salta completamente b, non viene valutata affatto e) dice: a
è il mio risultato ( NON : Falso è il mio risultato).
Se a
non risponde, and
chiede: qual è la tua lunghezza? (Ancora una volta, puoi personalizzarlo come autore della a
classe). Se a
risponde 0, and
fa lo stesso come sopra - lo considera falso ( NON falso), salta b e dà a
come risultato.
Se a
risponde a una domanda diversa da 0 alla seconda domanda ("qual è la tua lunghezza"), oppure non risponde affatto o risponde "sì" alla prima ("sei vero"), and
valuta b e dice: b
è il mio risultato. Si noti che lo fa non chiedere b
a qualsiasi domanda.
L'altro modo di dire tutto ciò è a and b
quasi lo stesso b if a else a
, tranne che a viene valutato una sola volta.
Ora siediti qualche minuto con carta e penna e convinciti che quando {a, b} è un sottoinsieme di {True, False}, funziona esattamente come ti aspetteresti dagli operatori booleani. Ma spero di averti convinto che è molto più generale e, come vedrai, molto più utile in questo modo.
Mettendo insieme quei due
Ora spero che tu capisca il tuo esempio 1. and
non importa se mylist1 è un numero, elenco, lambda o un oggetto di una classe Argmhbl. Si preoccupa solo della risposta di mylist1 alle domande del protocollo. E, naturalmente, mylist1 risponde 5 alla domanda sulla lunghezza, quindi restituisce mylist2. E questo è tutto. Non ha nulla a che fare con gli elementi di mylist1 e mylist2: non entrano nell'immagine da nessuna parte.
Secondo esempio: &
onlist
D'altra parte, &
è un operatore come un altro, come +
ad esempio. Può essere definito per un tipo definendo un metodo speciale su quella classe. int
lo definisce come bit per bit "e", e bool lo definisce come logico "e", ma questa è solo un'opzione: per esempio, set e alcuni altri oggetti come le viste dei tasti dict lo definiscono come un incrocio impostato. list
semplicemente non lo definisce, probabilmente perché Guido non ha pensato a un modo ovvio per definirlo.
numpy
Dall'altra parte MrGreen, gli array intorpiditi sono speciali, o almeno stanno cercando di esserlo. Ovviamente numpy.array è solo una classe, non può ignorare and
in alcun modo, quindi fa la cosa migliore successiva: quando viene chiesto "sei vero", numpy.array genera un ValueError, dicendo efficacemente "per favore riformula la domanda, mio la visione della verità non rientra nel tuo modello ". (Nota che il messaggio ValueError non parla di and
- perché numpy.array non sa chi lo sta ponendo la domanda; parla solo di verità.)
Perché &
è una storia completamente diversa. numpy.array può definirlo come desidera e definisce &
coerentemente con altri operatori: in senso puntuale. Quindi finalmente ottieni quello che vuoi.
HTH,
np.bitwise_and()
enp.logical_and()
e gli amici per evitare confusione.