Какая польза от оператора тильды в Python?
Одна вещь, о которой я могу подумать, это сделать что-то с обеих сторон строки или списка, например, проверить, является ли строка палиндромной или нет:
def is_palindromic(s):
return all(s[i] == s[~i] for i in range(len(s) / 2))
Любое другое хорошее использование?
~
реализованный специальным методом,__invert__
не связан сnot
оператором, который логически сводит на нет значение, возвращаемое__bool__
(или__nonzero__
в 2.x). Это также не связано с-
унарным оператором отрицания, реализованным__neg__
. Например~True == -2
, который не являетсяFalse
или ложным, и-False == 0
, который все еще ложным.-False==0
) Это сбивает с толку, так как вы говорили о~
, и~False == -1
это не Ложь.__neg__
). Вероятно, мне следовало бы продолжать использоватьTrue
, например-True == -1
, значение «-2» или «False
ложь», которое более четко связывает его с~True
результатом, а также то, что арифметическое отрицание abool
отличается от его логического отрицания. Я не пытался быть глубоким. Я просто выделил 3 операции и основные специальные методы, которые иногда путают.Ответы:
Это унарный оператор (с одним аргументом), заимствованный из C, где все типы данных - это просто разные способы интерпретации байтов. Это операция «инвертировать» или «дополнить», в которой все биты входных данных инвертируются.
В Python для целых чисел биты представления целого числа, дополняющего двойку, инвертируются (как
b <- b XOR 1
для каждого отдельного бита), и результат снова интерпретируется как целое число, дополняющее двойку. Так что для целых чисел,~x
эквивалентно(-x) - 1
.Уточненная форма
~
оператора предоставляется в видеoperator.invert
. Чтобы поддержать этот оператор в вашем собственном классе, дайте ему__invert__(self)
метод.Любой класс, в котором имеет смысл иметь «дополнение» или «инверсию» экземпляра, который также является экземпляром того же класса, является возможным кандидатом на оператор инвертирования. Однако перегрузка операторов может привести к путанице при неправильном использовании, поэтому убедитесь, что это действительно имеет смысл, прежде чем предоставлять
__invert__
метод вашему классу. (Обратите внимание, что строки байтов [ex:'\xff'
] не поддерживают этот оператор, даже если имеет смысл инвертировать все биты строки байтов.)источник
~
является побитовым оператором дополнения в Python, который по существу вычисляет-x - 1
Так будет выглядеть таблица
Так что для
i = 0
этого будет по сравнениюs[0]
сs[len(s) - 1]
, дляi = 1
,s[1]
сs[len(s) - 2]
.Что касается вашего другого вопроса, это может быть полезно для целого ряда побитовых хаков .
источник
Помимо того, что он является побитовым оператором дополнения, он
~
также может помочь вернуть логическое значение, хотя здесь это не обычныйbool
тип, скорее, вы должны использоватьnumpy.bool_
.Это объясняется в
Изменение логического значения иногда может быть полезно, например,
~
оператор ниже используется для очистки вашего набора данных и возврата вам столбца без NaN.источник
numpy.NaN
кажется, определяется какnumpy.float
. Если я пытаюсь~numpy.NaN
, python жалуется, что унарный оператор~
не определен для типаnumpy.float
.~True
приводит к-2
, в то время как для NumPy Booleans~np.True_
приводит кFalse
.Следует отметить, что в случае индексации массивов,
array[~i]
составляетreversed_array[i]
. Это можно рассматривать как индексирование, начиная с конца массива:источник
~i
(т. Е. Отрицательное значение), действует как отправная точка для индекса массива, который Python с радостью принимает, заставляя индекс обернуться и выбрать его сзади.Единственный раз, когда я использовал это на практике, это с
numpy/pandas
. Например, с помощью.isin()
метода dataframe .В документах они показывают этот основной пример
Но что если вместо этого вы хотите, чтобы все строки отсутствовали в [0, 2]?
источник
Я решал эту проблему с помощью кода leetcode и наткнулся на это прекрасное решение от пользователя по имени Zitao Wang .
Проблема идет так: для каждого элемента в данном массиве найти произведение всех оставшихся чисел без использования деления и
O(n)
времениСтандартное решение:
Его решение использует только один цикл for, используя. Он вычисляет левый продукт и правый продукт на лету, используя
~
источник
Это незначительное использование это тильда ...
приведенный выше код взят из "Практического обучения машин"
вы используете тильду (~ знак) в качестве альтернативы - подписать маркер индекса
так же, как вы используете минус - для целого индекса
ех)
это то же самое, что
print(array[~1])
источник