Про 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()та друзі, щоб уникнути плутанини.