15

में '~' (tilde) ऑपरेटर के अनुप्रयोगों ने मुझे this question के माध्यम से पाइथन में bitwise complement unary operation की खोज की है और इसके लिए वास्तविक एप्लिकेशन के साथ आने का प्रयास कर रहे हैं, और यदि नहीं, तो यह निर्धारित करने के लिए कि यह आमतौर पर ओवरलोड करने के लिए सुरक्षित है या नहीं अन्य उपयोगों के लिए ऑपरेटर (__invert__ विधि ओवरराइड करके)। प्रश्न में दिया गया उदाहरण TypeError के साथ विफल रहता है, और link प्रदान किया गया है जो बहुत डरावना लगता है। यहाँ कुछ नगण्य आसपास उपयोग में ~ को देखने के लिए है:पायथन

from bitstring import BitArray 

x = 7 

print(~x) 
# -8 

print(BitArray(int=x, length=4).bin) 
# '0111' 

print(BitArray(int=~x, length=4).bin) 
# '1000' 

print(~~True, ~~False) 
# 1 0 

for i in range(-100, 100): 
    assert i + ~i == -1 
    assert i^~i == -1 
    assert bool(i) == ~~bool(i) 

वहाँ किसी भी इस ऑपरेटर है कि मैं के बारे में पता होना चाहिए के लिए मान्य उपयोग-मामले के उदाहरण हैं? और यहां तक ​​कि यदि भी हैं, तो क्या यह आमतौर पर int के अलावा अन्य प्रकार के लिए इस ऑपरेटर को ओवरराइड करने के लिए स्वीकार्य है?

+6

numpy/पांडा में, यह elementwise के लिए प्रयोग किया जाता है सरणी की तुलना। उदाहरण के लिए, यदि 'arr = [True, गलत, True]', '~ arr' लौटाता है [गलत, सही, गलत]'। – ayhan

+0

@ayhan यह अच्छा है, तो यह एक कास्टिंग नियम लागू करता है? ऐसा लगता है कि यह इंट्स के सरणी के लिए भी काम करता है, लेकिन 'int' और 'bool' के संयोजन के दौरान टूट जाता है: '~ np.array ([1, 0, -1, True, False]) -> सरणी ([ -2, -1, 0, -2, -1]) '। 'Bool' मानों को 'int' मानों में परिवर्तित करने के लिए एक मजेदार चाल के रूप में उपयोग किया जा सकता है हालांकि:' ~~ (np.array ([True, False] + [1])) [: - 1] -> सरणी ([1] , 0]) ' – Alec

+1

@ एलेक या तो आपके पास 'बूल' या 'int' की सरणी है। 'बूल' और 'int' को मिलाकर 'int' सरणी उत्पन्न होती है। – Bakuriu

उत्तर

12

बिटवाइज़ नहीं ऑपरेटर के लिए मानक उपयोग के मामलों बिटवाइज़ संचालन, बस बिटवाइज़ और &, बिटवाइज़ या |, बिटवाइज़ XOR ^, और बिटवाइज़ << और >> स्थानांतरण की तरह हैं। यद्यपि वे शायद ही कभी उच्च स्तर के अनुप्रयोगों में उपयोग किए जाते हैं, फिर भी कुछ समय होते हैं जहां आपको थोड़ा सा काम करने की आवश्यकता होती है, इसलिए यही कारण है कि वे वहां हैं।

बेशक, आप इन्हें कस्टम प्रकारों के लिए ओवरराइट कर सकते हैं, और आम तौर पर ऐसा करने पर आपको किसी भी विशिष्ट अर्थशास्त्र का पालन करने की आवश्यकता नहीं होती है। बस चुनें कि आपके प्रकार के लिए क्या समझ में आता है और ऑपरेटर को किसी भी तरह से फिट करता है।

यदि ऑपरेशन अस्पष्ट है और किसी शब्द या दो के साथ बेहतर समझाया गया है, तो आपको इसके बजाय मानक विधि का उपयोग करना चाहिए। लेकिन कुछ स्थितियां हैं, खासकर जब संख्या संबंधित प्रकारों के साथ काम करते हैं, जिनमें कुछ गणितीय-जैसे ऑपरेशन हो सकते हैं जो बिटवाई ऑपरेटरों के अनुरूप होते हैं, और ऐसे में उपयोग करने के लिए ठीक हैं।

जैसे ही आप मानक ऑपरेटरों जैसे + और - केवल सार्थक परिचालनों के लिए ओवरराइट करेंगे, आपको बिटवाई ऑपरेटरों के लिए ऐसा करने की कोशिश करनी चाहिए। क्योंकि bool प्रकार अपनी ही __invert__ आपरेशन को परिभाषित नहीं करता


कारण ~~True, ~~False आप (1, 0) देता है। हालांकि, int करता है; और bool वास्तव में int का एक उप प्रकार है। तो bool वास्तव में सभी bitwise और अंकगणितीय ऑपरेटरों के तर्क विरासत में मिलता है। इसलिए True + True == 2 आदि

+0

यह समझ में आता है! तो '' '' '' 'कीवर्ड के साथ कोई समानता नहीं है? मेरी शुरुआती जांच मुझे विश्वास दिलाती है कि 'नहीं' '' 'को मैप नहीं करता है और केवल वास्तव में बूलियन मानों पर लागू होता है। – Alec

+1

हाँ, आप सही हैं। 'नहीं 'एक बुलियन नहीं ऑपरेटर है जबकि' ~ 'थोड़ा सा ऑपरेटर नहीं है। बिटवाई '~' को कार्यान्वित करने से नतीजे को 'नहीं' कीवर्ड का उपयोग करने से प्रभावित नहीं होगा। 'एक्स' सामान्य रूप से 'बूल (एक्स)' के बराबर नहीं है, जो इसके बजाय विशेष विधि '__bool__' कहता है (जिसे एक बूल बीटीडब्ल्यू वापस करना है।)। – poke

6

Are there any examples of valid use-cases for this operator that I should be aware of? And even if there are, is it generally acceptable to override this operator for types other than int?

आमतौर पर, आप ~ ऑपरेटर ओवरलोड सिर्फ इसलिए कि यह मजेदार है नहीं करना चाहते। यह पढ़ना मुश्किल बनाता है। लेकिन कभी-कभी, int के अलावा अन्य प्रकार के लिए इस तरह के अधिभार को समझ में आता है। Take a look at how SQLAlchemy puts it to good use.

+0

यह दिलचस्प है, इसलिए SQLAlchemy इसे स्तंभों पर 'इन नहीं' ऑपरेशन के प्रतिस्थापन के रूप में उपयोग करता है? – Alec

+3

यह एक 'नहीं' ऑपरेटर है, न कि 'IN IN' ऑपरेटर। – SuperSaiyan

+1

आह, मैंने लिंक को ध्यान से पर्याप्त रूप से नहीं पढ़ा था। सुधार करने के लिए धन्यवाद! – Alec

2

आप निषेध ऑपरेटर (-) के साथ संयोजन के रूप में है कि ऑपरेटर का उपयोग कर सकते 1. द्वारा एक संख्या को बढ़ाना उदाहरण के लिए:

x = 5 
assert -~x == 6 

यह केवल व्यावहारिक तरीका मैंने कभी किया है है ~ ऑपरेटर का उपयोग किया। किसी भी अन्य तरीके से इसे संख्याओं के अलावा किसी भी चीज़ के लिए उपयोग किया जाता है, आमतौर पर संदर्भ निर्भर होता है और अक्सर कोड को समझने के लिए जटिलता का स्तर जोड़ता है। जैसे C++ स्विफ्ट, रूबी, आदि के रूप में भाषाओं के लिए, आप कुछ भी है जो कभी कभी जल्दी से पचाने के लिए कोड कठिन बना देता है मतलब करने के लिए इस ऑपरेटर को ओवरलोड कर सकते हैं

+4

'- ~ x' (या उसके मित्र '~ -x') को कम से कम उपयोगी उपयोगों में से एक होना चाहिए – harold

+0

@harold यह शायद सच है, लेकिन मैंने कभी भी किसी भी अन्य संस्करण का उपयोग नहीं किया है जो मैंने पोस्ट किया है उससे अधिक उपयोगी है । क्या आप किसी और का सुझाव दे सकते हैं? – smac89

+0

और यहां मैंने सोचा कि जगह में वृद्धि करना पायथन में नियमों के खिलाफ था :) मुझे लगता है कि मैंने इसे कोड गोल्फ उदाहरणों में पहले देखा है, इससे पहले कि आप इसका उल्लेख करते हैं (ऐसा नहीं है कि इसे पढ़ने योग्य कोड में उपयोग करने का मामला उसमें सुधार हुआ है अवलोकन!) – Alec

2

यह आमतौर पर इस तरह के का उपयोग कर के रूप में कुछ बातें, के लिए एक शॉर्टकट के रूप code golf में प्रयोग किया जाता है के बजाय -x-1 या ~my_bool के बजाय ~x

0

जैसा कि अन्य ने उल्लेख किया है, यह सूचियों की खोज करते समय वास्तव में साफ हो सकता है।

for i in range(n): 
    mylist[~i] 
    #much prettier than mylist[-i-1] 

एक उदाहरण है जो 90 डिग्री से एक मैट्रिक्स दक्षिणावर्त घूमता है पर एक नज़र डालें:

def rotate(A): 
    n = len(A) 
    for i in range(n/2): 
     for j in range(n-n/2): 
      A[i][j], A[~j][i], A[~i][~j], A[j][~i] = \\ 
        A[~j][i], A[~i][~j], A[j][~i], A[i][j] 

(यह स्निपेट here से लिया गया है)