Про list
Спочатку дуже важливий момент, з якого все буде випливати (сподіваюся).
У звичайному Python list
не є особливим у жодному разі (крім того, що милий синтаксис для побудови, що здебільшого є історичною випадковістю). Після того, як список [3,2,6]
складається, він для всіх намірів і цілей є просто звичайним об'єктом Python, таким як число 3
, набір {3,7}
або функція lambda x: x+5
.
(Так, він підтримує зміну своїх елементів, він підтримує ітерацію та багато інших речей, але це лише такий тип: він підтримує деякі операції, а не підтримує деякі інші. Int підтримує підвищення до потужності, але це не робить зробити його дуже особливим - це просто те, що таке int. лямбда підтримує дзвінки, але це не робить його дуже особливим - саме для цього і є лямбда :).
Про and
and
не є оператором (ви можете назвати його "оператором", але ви можете також зателефонувати "для" оператора :). Оператори в Python - це (реалізовані через) методи, викликані на об'єктах певного типу, зазвичай записаних як частина цього типу. Немає способу проводити оцінку деяких своїх операндів, але це and
може (і повинно) зробити це.
Наслідком цього є те, що and
не можна перевантажувати, як for
не можна перевантажувати. Він повністю загальний і спілкується через визначений протокол. Що ви можете зробити, це налаштувати свою частину протоколу, але це не означає, що ви можете повністю змінити поведінку and
. Протокол:
Уявіть, що Python інтерпретує "a і b" (це відбувається не буквально так, але це допомагає зрозуміти). Коли йдеться про "і", він дивиться на об'єкт, який він щойно оцінив (а), і запитує його: ти правдивий? ( НЕ : ти True
?) Якщо ви автор класу, ви можете налаштувати цю відповідь. Якщо a
відповіді "ні", and
(пропускає b повністю, це зовсім не оцінюється, і) каже: a
це мій результат ( НЕ : Неправдивий - це мій результат).
Якщо a
не відповідає, and
запитайте: яка ваша довжина? (Знову ж, ви можете налаштувати це як автор a
класу). Якщо a
відповідь 0, and
робить те саме, що вище - вважає помилковим ( НЕ помилковим), пропускає b і дає a
результат.
Якщо a
на друге запитання відповідає щось інше, ніж 0 ("яка ваша довжина"), або вона взагалі не відповідає, або відповідає "так" на перше ("ви правдиві"), and
оцінює b і каже: b
це мій результат. Зауважте, що він НЕ задає b
жодних питань.
Інший спосіб сказати все це - a and b
це майже те саме, що b if a else a
, за винятком а, оцінюється лише один раз.
Тепер посидьте кілька хвилин ручкою та папером і переконайте себе, що коли {a, b} є підмножиною {True, False}, вона працює точно так, як ви очікували від булевих операторів. Але я сподіваюся, що я переконав вас, що це набагато загальніше, і як ви побачите, цей спосіб набагато корисніший.
Поєднання цих двох разом
Тепер я сподіваюся, що ви зрозуміли ваш приклад 1. and
Байдуже, чи mylist1 - це число, список, лямбда або об’єкт класу Argmhbl. Це просто піклується про відповідь mylist1 на запитання протоколу. І звичайно, mylist1 відповідає 5 на запитання про довжину, тому повертає mylist2. І це все. Це не має нічого спільного з елементами mylist1 та mylist2 - вони ніде не вводять зображення.
Другий приклад: &
наlist
З іншого боку, &
це оператор, як і будь-який інший, як +
наприклад. Це можна визначити для типу, визначивши спеціальний метод для цього класу. int
визначає його як бітові "та", а bool визначає це як логічні "та", але це лише один варіант: наприклад, набори та деякі інші об'єкти, такі як погляди клавіш dict, визначають його як перетин набору. list
просто не визначає це, ймовірно, тому, що Гвідо не думав про якийсь очевидний спосіб його визначення.
онімілий
На іншій нозі: -D, Numpy масиви є спеціальними, або , по крайней мере , вони намагаються бути. Звичайно, numpy.array - це просто клас, він не може переоцінити and
жодним чином, тому він робить наступне найкраще: коли запитують "ти правдивий", numpy.array піднімає ValueError, ефективно кажучи "будь ласка, перефразуйте питання, мій погляд на правду не вписується у вашу модель ". (Зверніть увагу, що повідомлення ValueError не говорить про те, and
тому що numpy.array не знає, хто йому задає це питання; воно просто говорить про правду.)
Бо &
це зовсім інша історія. numpy.array може визначати його за своїм бажанням, і він визначає &
послідовно з іншими операторами: в точку. Так ви нарешті отримуєте те, що хочете.
HTH,
np.bitwise_and()
іnp.logical_and()
та друзі, щоб уникнути плутанини.