Оператор тильды в Python

Какое использование оператора тильды в Python?

Одна вещь, о которой я могу думать, - это сделать что-то в обеих сторонах строки или списка, например, проверить, является ли строка палиндромной или нет:

def is_palindromic(s):
    return all(s[i] == s[~i] for i in range(len(s) / 2)) 

Любое другое хорошее использование?

Ответ 1

Это унарный оператор (принимающий один аргумент), который заимствован из C, где все типы данных - это просто разные способы интерпретации байтов. Это операция "инвертировать" или "дополнение", в которой все биты входных данных меняются на противоположные.

В Python для целых чисел биты двухкомпонентного представления целого числа обращаются вспять (как в b <- b XOR 1 для каждого отдельного бит), и результат интерпретируется снова как целое число с двумя дополнениями. Итак, для целых чисел ~x эквивалентно (-x) - 1.

Обоснованная форма оператора ~ предоставляется как operator.invert. Чтобы поддерживать этот оператор в своем классе, дайте ему метод __invert__(self).

>>> import operator
>>> class Foo:
...   def __invert__(self):
...     print 'invert'
...
>>> x = Foo()
>>> operator.invert(x)
invert
>>> ~x
invert

Любой класс, в котором имеет смысл иметь "дополнение" или "обратное" экземпляра, который также является экземпляром одного и того же класса, является возможным кандидатом для инвертирующего оператора. Однако перегрузка оператора может привести к путанице при неправильном использовании, поэтому убедитесь, что это действительно имеет смысл сделать, прежде чем предоставлять метод __invert__ для вашего класса. (Обратите внимание, что байт-строки [ex: '\xff'] не поддерживают этот оператор, хотя имеет смысл инвертировать все биты байтовой строки.)

Ответ 2

~ - это оператор побитового дополнения в python, который по существу вычисляет -x - 1

Итак, таблица будет выглядеть как

i  ~i  
0  -1
1  -2
2  -3
3  -4 
4  -5 
5  -6

Итак, для i = 0 он сравнивал бы s[0] с s[len(s) - 1], для i = 1, s[1] с s[len(s) - 2].

Что касается вашего другого вопроса, это может быть полезно для диапазона побитовых хаков.

Ответ 3

Кроме того, что он является побитовым оператором дополнения, ~ также может возвращать логическое значение, хотя здесь нет обычного типа bool, скорее, вы должны использовать numpy.bool_.


Это объясняется в

import numpy as np
assert ~np.True_ == np.False_

Иногда может быть полезно обратное логическое значение, например, ниже ~ используется оператор, чтобы очистить ваш набор данных и вернуть вам столбец без NaN.

from numpy import NaN
import pandas as pd

matrix = pd.DataFrame([1,2,3,4,NaN], columns=['Number'], dtype='float64')
# Remove NaN in column 'Number'
matrix['Number'][~matrix['Number'].isnull()]

Ответ 4

Следует отметить, что в случае индексации array[~i] равняется reversed_array[i]. Это можно рассматривать как индексирование, начиная с конца массива:

[0, 1, 2, 3, 4, 5, 6, 7, 8]
    ^                 ^
    i                ~i

Ответ 5

Это незначительное использование это тильда...

def split_train_test_by_id(data, test_ratio, id_column):
    ids = data[id_column]
    in_test_set = ids.apply(lambda id_: test_set_check(id_, test_ratio)) 
    return data.loc[~in_test_set], data.loc[in_test_set]

вышеприведенный код взят из "Hands On Machine Learning"

Вы используете тильду (~ знак) в качестве альтернативы - подписать маркер индекса

так же, как вы используете минус - для целочисленного индекса

ех)

array = [1,2,3,4,5,6]
print(array[-1])

это то же самое, что

print(array[~1])