पायथन में टिल्ड ऑपरेटर


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जो अभी भी गलत है।
एरिक सन

@eryksun, हालांकि आपने जो कहा वह सही है ( -False==0) इसकी उलझन, चूंकि आप के बारे में बात कर रहे थे ~, और ~False == -1जो गलत नहीं है।
गुइलहर्मे डे लाज़री

3
@ गुइलहर्माडेलाज़री, दूसरा उदाहरण अंकगणितीय नकार ( __neg__) के साथ तुलना करना था । संभवत: मुझे इसका उपयोग जारी रखना चाहिए True, उदाहरण के लिए -True == -1, जो -2 या Falseगलत नहीं है, जो इसे स्पष्ट रूप से ~Trueपरिणाम में वापस जोड़ता है और यह भी कि अंकगणित की उपेक्षा boolइसके तार्किक निषेध से अलग है। मैं गहरी होने की कोशिश नहीं कर रहा था। मैं सिर्फ 3 ऑपरेशन और अंतर्निहित विशेष तरीकों को उजागर कर रहा था जो कभी-कभी भ्रमित हो जाते हैं।
एर सन सन

जवाबों:


192

यह एक unary ऑपरेटर है (एकल तर्क ले रहा है) C से उधार लिया गया है, जहाँ सभी डेटा प्रकार बाइट्स की व्याख्या करने के विभिन्न तरीके हैं। यह "इनवर्ट" या "पूरक" ऑपरेशन है, जिसमें इनपुट डेटा के सभी बिट्स उलट होते हैं।

पायथन में, पूर्णांक के लिए, पूर्णांक के दो-पूरक प्रतिनिधित्व के 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__आपकी कक्षा के लिए एक विधि की आपूर्ति करने से पहले वास्तव में ऐसा करने के लिए समझ में आता है । (ध्यान दें कि बाइट-स्ट्रिंग्स [एक्स: '\xff'] इस ऑपरेटर का समर्थन नहीं करते हैं, भले ही यह बाइट-स्ट्रिंग के सभी बिट्स को उलटने के लिए सार्थक है।)


16
अच्छी व्याख्या, लेकिन सावधानी का एक शब्द - ऑपरेटर ओवरलोडिंग के लिए सभी सुरक्षा अस्वीकरण यहां लागू होते हैं - यह एक अच्छा विचार नहीं है, जब तक कि यह बिल पूरी तरह से फिट न हो।
एली बेंडरस्की 3

एली की प्रतिक्रिया को अंतिम पैराग्राफ में उत्तर में शामिल किया गया है।
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

एक बिटवाइज़ पूरक ऑपरेटर होने के अलावा, ~एक बूलियन मूल्य को वापस करने में भी मदद कर सकता है , हालांकि यह 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()]

numpy.NaNके रूप में परिभाषित किया जा रहा है numpy.float। अगर मैं कोशिश करता हूं ~numpy.NaN, तो अजगर शिकायत करता है, कि यूनिरी ऑपरेटर ~को प्रकार के लिए परिभाषित नहीं किया गया है numpy.float
M.Herzkamp

2
@ M.Herzkamp, ​​यह सही है। NaN, + Inf, और -इन फ़्लोटिंग-पॉइंट नंबरों के विशेष मामले हैं। फ्लोटिंग पॉइंट नंबर के बिट्स इन्वर्ट करने से एक निरर्थक परिणाम उत्पन्न होगा, इसलिए पायथन इसकी अनुमति नहीं देता है। इसलिए आपको पहले अपने डेटा ऐरे पर .isnull () या np.isnan () कॉल करने की आवश्यकता है, और फिर परिणामस्वरूप बूलियन मानों को उल्टा करें।
जियोफली

7
ध्यान दें, कि ~Trueपरिणाम के रूप में -2, जबकि सुन्न मल के लिए ~np.True_परिणाम है False
क्रिश्चियन हरेंज

अच्छा सुझाव! मैंने इसे एक डेटासेट के माध्यम से क्रमबद्ध करने के लिए यहाँ देखा था: 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(नकारात्मक मान) से निकलता है वह सरणी इंडेक्स के लिए एक प्रारंभिक बिंदु के रूप में कार्य करता है जो अजगर खुशी से स्वीकार करता है जिससे सूचकांक चारों ओर से लपेटता है और पीछे से उठाता है।
चीख

4

केवल समय मैंने कभी भी इस अभ्यास में उपयोग किया है numpy/pandas। उदाहरण के लिए, .isin() डेटाफ्रेम विधि के साथ

डॉक्स में वे इस मूल उदाहरण को दिखाते हैं

>>> 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 नाम के एक उपयोगकर्ता ने इस सुंदर समाधान के बारे में बताया

समस्या दी गई सरणी में प्रत्येक तत्व के लिए इस तरह से जाती है, शेष सभी नंबरों के उत्पाद को बिना डिविज़न और 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 

उसका समाधान केवल एक का उपयोग करके लूप के लिए उपयोग करता है। वह मक्खी के उपयोग पर बाएं उत्पाद और दाएं उत्पाद की गणना करता है~

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]

उपरोक्त कोड "हैंड्स ऑन मशीन लर्निंग" से है

आप के रूप में वैकल्पिक - चिह्न सूचकांक मार्कर के रूप में टिल्ड (~ साइन) का उपयोग करते हैं

जैसे आप माइनस का उपयोग करते हैं - पूर्णांक सूचकांक के लिए है

पूर्व)

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

के रूप में नमूना है

print(array[~1])

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.