파이썬의 물결표 연산자


199

파이썬에서 물결표 연산자의 사용법은 무엇입니까?

내가 생각할 수있는 한 가지는 문자열이 회 문형인지 아닌지 확인하는 것과 같이 문자열이나 목록의 양쪽에서 무언가를하는 것입니다.

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

다른 좋은 사용법?


11
~특수한 방법으로 구현 된 단항 보수 연산자 __invert__not연산자 와 관련이 없으며 ,이 연산자는 __bool__(또는 __nonzero__2.x에서) 반환 된 값을 논리적으로 무시합니다 . 또한에 -의해 구현되는 단항 부정 연산자 와 관련이 없습니다 __neg__. 예를 들어 ~True == -2, 이는 False거짓 이 아니며 -False == 0여전히 거짓입니다.
Eryk Sun

무엇을 당신이 말한 것은 (오른쪽 비록 @eryksun, -False==0) 그것의 당신이에 대해 얘기했다 이후, 혼란 ~, 그리고 ~False == -1어떤 것은 거짓이 아니다.
Guilherme de Lazari

3
@GuilhermedeLazari, 두 번째 예는 산술 부정 ( __neg__) 과 비교하는 것 입니다. 아마도 True예를 들어 -True == -1-2 또는 Falsefalse 가 아닌 을 계속 사용했을 것입니다 . ~True결과 는 결과와 더 명확하게 연결 되며 a의 산술 부정은 bool논리적 부정과 다릅니다. 나는 깊이하려고하지 않았습니다. 방금 혼란스러워하는 3 가지 작업과 기본 특수 메소드를 강조했습니다.
Eryk Sun

답변:


192

C에서 빌려온 단항 연산자 (단일 인수 사용)는 모든 데이터 유형이 바이트를 해석하는 다른 방식 일뿐입니다. 입력 데이터의 모든 비트가 반전되는 "반전"또는 "보완"연산입니다.

파이썬에서 정수의 경우 정수의 2 보수 표현 의 비트 가 반전되고 ( b <- b XOR 1각 개별 비트에서와 같이) 결과는 2 보수 정수로 다시 해석됩니다. 따라서 정수의 경우 ~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']는 바이트 열의 모든 비트를 반전시키는 것이 의미가 있더라도이 연산자를 지원하지 않습니다.


16
좋은 설명이지만주의해야 할 점-운영자 과부하에 대한 모든 안전 면책 조항이 여기에 적용됩니다.
Eli Bendersky

Eli의 피드백은 마지막 단락의 답변에 포함되었습니다.
wberry

91

~본질적으로 계산하는 파이썬 의 비트 보수 연산자 입니다.-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].

다른 질문에 관해서는, 이것은 다양한 비트 해킹에 유용 할 수 있습니다 .


26

비트 보수 연산자 외에도 부울 값을 ~되 돌리는 데 도움이 될 수 있지만 여기에서는 일반적인 유형 이 아니지만 을 사용해야합니다 .boolnumpy.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()]

numpy.NaN로 정의 된 것 같습니다 numpy.float. 내가 시도 ~numpy.NaN하면 파이썬은 단항 연산자 ~가 type에 대해 정의되어 있지 않다고 불평 합니다 numpy.float.
M.Herzkamp

2
@ M.Herzkamp, ​​맞습니다. NaN, + Inf 및 -Inf는 부동 소수점 숫자의 특수한 경우입니다. 부동 소수점 숫자의 비트를 반전하면 의미가없는 결과가 생성되므로 Python에서는 허용하지 않습니다. 따라서 데이터 배열에서 .isnull () 또는 np.isnan ()을 먼저 호출 한 다음 결과 부울 값을 반전시켜야합니다.
geofflee

7
참고, 그 ~True결과 -2잠시 NumPy와 논리 값에 대한, ~np.True_결과 False.
Christian Herenz

좋은 팁! : 나는 데이터 집합을 정렬 여기에 사용했다 github.com/yu4u/age-gender-estimation/blob/master/create_db.py
mLstudent33

19

배열 인덱싱의 경우에 array[~i]해당합니다 reversed_array[i]. 배열의 끝에서 시작하여 인덱싱으로 볼 수 있습니다.

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

2
그것은 주로 나오는 값 ~i(즉, 음수 값)이 파이썬이 인덱스를 감싸서 뒤에서 따기 위해 행복하게 받아들이는 배열 인덱스의 시작점으로 작용하기 때문입니다.
shriek 2018 년

4

내가 실제로 이것을 사용한 유일한 시간은입니다 numpy/pandas. 예를 들어, .isin() dataframe method를 사용하십시오 .

문서에서 그들은이 기본 예제를 보여줍니다

>>> df.isin([0, 2])
        num_legs  num_wings
falcon      True       True
dog        False       True

그러나 대신 [0, 2]에 없는 모든 행을 원한다면 어떻게해야 합니까?

>>> ~df.isin([0, 2])
        num_legs  num_wings
falcon     False       False
dog        True        False

2

나는이 leetcode 문제를 해결하고 있었고 Zitao Wang 이라는 사용자 가이 아름다운 솔루션 을 발견했습니다 .

문제는 divison과에서 사용하지 않고 남아있는 모든 숫자의 제품을 찾을 수 지정된 배열의 각 요소에 대해 이렇게되면 O(n)시간을

표준 솔루션은 다음과 같습니다.

Pass 1: For all elements compute product of all the elements to the left of it
Pass 2: For all elements compute product of all the elements to the right of it
        and then multiplying them for the final answer 

그의 솔루션은 사용하여 하나의 for 루프 만 사용합니다. 그는 왼쪽 제품과 오른쪽 제품을 사용하여 즉석에서 계산합니다.~

def productExceptSelf(self, nums):
    res = [1]*len(nums)
    lprod = 1
    rprod = 1
    for i in range(len(nums)):
        res[i] *= lprod
        lprod *= nums[i]
        res[~i] *= rprod
        rprod *= nums[~i]
    return res

-2

이것은 사소한 사용법은 물결표입니다 ...

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])

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.