पायथन में एक मूल्य को कैसे टॉगल करें


128

0और के बीच टॉगल करने का सबसे कुशल तरीका क्या है 1?


जब यह सवाल पूछता है कि बाइनरी तरीके से मूल्यों को सबसे कुशलता से कैसे टॉगल किया जाए, तो कुछ जवाब साइकल के माध्यम से (मनमाने ढंग से) मूल्यों को समझाते हैं, जैसे stackoverflow.com/a/61041907/537865
पागल

जवाबों:


273

समाधान का उपयोग नहीं

यदि मान बूलियन हैं, तो सबसे तेज़ तरीका ऑपरेटर का उपयोग नहीं करना है:

>>> x = True
>>> x = not x        # toggle
>>> x
False
>>> x = not x        # toggle
>>> x
True
>>> x = not x        # toggle
>>> x
False

घटाव का उपयोग कर समाधान

यदि मान संख्यात्मक हैं, तो कुल से घटाव मूल्यों को टॉगल करने का एक सरल और तेज़ तरीका है:

>>> A = 5
>>> B = 3
>>> total = A + B
>>> x = A
>>> x = total - x    # toggle
>>> x
3
>>> x = total - x    # toggle
>>> x
5
>>> x = total - x    # toggle
>>> x
3

XOR का उपयोग कर समाधान

यदि मान 0 और 1 के बीच टॉगल करता है , तो आप एक बिटवाइज़ अनन्य-या का उपयोग कर सकते हैं :

>>> x = 1
>>> x ^= 1
>>> x
0
>>> x ^= 1
>>> x
1

तकनीक पूर्णांक के किसी भी जोड़े को सामान्यीकृत करती है। Xor-by-one चरण को xor-by-precomputed-निरंतर के साथ बदल दिया गया है:

>>> A = 205
>>> B = -117
>>> t = A ^ B        # precomputed toggle constant
>>> x = A
>>> x ^= t           # toggle
>>> x
-117
>>> x ^= t           # toggle
>>> x
205
>>> x ^= t           # toggle
>>> x
-117

(यह विचार Nick Coghlan द्वारा प्रस्तुत किया गया था और बाद में @zxxc द्वारा सामान्यीकृत किया गया।)

एक शब्दकोश का उपयोग कर समाधान

यदि मूल्य उपलब्ध हैं, तो आप एक शब्दकोश का उपयोग कर सकते हैं:

>>> A = 'xyz'
>>> B = 'pdq'
>>> d = {A:B, B:A}
>>> x = A
>>> x = d[x]         # toggle
>>> x
'pdq'
>>> x = d[x]         # toggle
>>> x
'xyz'
>>> x = d[x]         # toggle
>>> x
'pdq'

सशर्त अभिव्यक्ति का उपयोग करके समाधान

सबसे सरल तरीका सशर्त अभिव्यक्ति का उपयोग करना है :

>>> A = [1,2,3]
>>> B = [4,5,6]
>>> x = A
>>> x = B if x == A else A
>>> x
[4, 5, 6]
>>> x = B if x == A else A
>>> x
[1, 2, 3]
>>> x = B if x == A else A
>>> x
[4, 5, 6]

Itertools का उपयोग कर समाधान

यदि आपके पास दो से अधिक मान हैं, तो itertools.cycle () फ़ंक्शन सामान्य मानों के बीच टॉगल करने का एक सामान्य तेज़ तरीका प्रदान करता है:

>>> import itertools
>>> toggle = itertools.cycle(['red', 'green', 'blue']).next
>>> toggle()
'red'
>>> toggle()
'green'
>>> toggle()
'blue'
>>> toggle()
'red'
>>> toggle()
'green'
>>> toggle()
'blue'

ध्यान दें कि पायथन 3 में next()विधि को बदल दिया गया था __next__(), इसलिए पहली पंक्ति को अब लिखा जाएगाtoggle = itertools.cycle(['red', 'green', 'blue']).__next__


अंतिम उदाहरण इतना धीमा और सहज लगता है, लेकिन .next () को हटाने के साथ पायथन 3+ में काम नहीं करता है। क्या अजगर के बाद के संस्करण में इसे समान रूप से काम करने का एक तरीका है?
लबराना

2
@labarna पायथन 3 में, .next()एक वैश्विक next()समारोह द्वारा प्रतिस्थापित किया गया है। उपरोक्त उदाहरण होगा:toggle = itertools.cycle(...); next(toggle)
बजे

2
toggle = itertools.cycle(['red', 'green', 'blue']) next(toggle)
मैक्सिमिलियन

7
XOR उदाहरण को मूल्यों aऔर bउपयोग के बीच टॉगल करने के लिए सामान्यीकृत किया जा सकता है x = x ^ (a ^ b)
zxxc

int(not 0)और int(not 1)... ह्म्म्म
jrr

33

मैं हमेशा उपयोग करता हूं:

p^=True

यदि पी एक बूलियन है, तो यह सच और गलत के बीच बदल जाता है।


1
उत्तम! pइस विधि को काम करने के लिए दो बार संदर्भित करने की आवश्यकता नहीं है !! यदि आप एक लंबे संदर्भ के साथ एक मूल्य टॉगल कर रहे हैं।
थोरसुमोनर

1
इस ऑपरेटर को क्या कहा जाता है?
मिक्स 3 डी

4
यह XOR ऑपरेटर है।
bastelflp

1
@ मिक्स 3 डी वास्तव में यह "बिटवाइज़ एक्सक्लूसिव या" ("लॉजिकल एक्सक्लूसिव या" के विपरीत) है - wiki.python.org/moin/BitwiseOperators । लॉजिकल एक्सओआर में सामान्य रूप से पायथन में एक विशिष्ट ऑपरेटर नहीं है, लेकिन आप इसे कुछ विशेष मामलों में लागू कर सकते हैं जैसे दशमलव मॉड्यूल में।
टेलर एडमिस्टन

@ मिक्स 3 डी ^=बिटवाइस एक्सोर असिगमेंट है
वेजेंड्रिया

23

यहाँ एक और गैर सहज तरीका है। सुंदरता यह है कि आप कई मूल्यों पर चक्र लगा सकते हैं और न केवल दो [0,1]

दो मूल्यों के लिए (टॉगल)

>>> x=[1,0]
>>> toggle=x[toggle]

एकाधिक मूल्यों के लिए (4 मानें)

>>> x=[1,2,3,0]
>>> toggle=x[toggle]

मुझे उम्मीद नहीं थी कि यह समाधान लगभग सबसे तेज़ होगा

>>> stmt1="""
toggle=0
for i in xrange(0,100):
    toggle = 1 if toggle == 0 else 0
"""
>>> stmt2="""
x=[1,0]
toggle=0
for i in xrange(0,100):
    toggle=x[toggle]
"""
>>> t1=timeit.Timer(stmt=stmt1)
>>> t2=timeit.Timer(stmt=stmt2)
>>> print "%.2f usec/pass" % (1000000 * t1.timeit(number=100000)/100000)
7.07 usec/pass
>>> print "%.2f usec/pass" % (1000000 * t2.timeit(number=100000)/100000)
6.19 usec/pass
stmt3="""
toggle = False
for i in xrange(0,100):
    toggle = (not toggle) & 1
"""
>>> t3=timeit.Timer(stmt=stmt3)
>>> print "%.2f usec/pass" % (1000000 * t3.timeit(number=100000)/100000)
9.84 usec/pass
>>> stmt4="""
x=0
for i in xrange(0,100):
    x=x-1
"""
>>> t4=timeit.Timer(stmt=stmt4)
>>> print "%.2f usec/pass" % (1000000 * t4.timeit(number=100000)/100000)
6.32 usec/pass

1
एक अखरोट के रूप में हाँ हाँ। सभी को धन्यवाद यह मजेदार है कि विभिन्न लोग समस्या (और सूचनात्मक) को कैसे देख रहे हैं

अच्छा, यह एक लघु राज्य मशीन है।
किंडल

ठीक है, आपका एक सबसे दिलचस्प है, लेकिन यह नहीं कि मुझे व्यक्तिगत रूप से उस चीज की आवश्यकता है जिसके बारे में मैं पूछ रहा था, ठीक है, मुझे लगता है कि सरल गणित एक तो मेरे लिए शायद सबसे अच्छा है, कि 1-x वहाँ नहीं होना चाहिए?

हाँ, लेकिन यह गति किसी भी अलग नहीं करना चाहिए।
ब्लेंडर

ऐ, लेकिन यह गलत नहीं होगा, हालांकि यह होगा? यहाँ कुछ महान जवाब, तो चट्टानों!

19

notऑपरेटर अपने चर को नकारता (यह एक बूलियन में परिवर्तित करता है, तो यह पहले से ही एक नहीं है)। आप कर सकते हैं शायद का उपयोग 1और 0के लिए भी Trueऔर False, इसलिए उसे यूं ही नकारना:

toggle = not toggle

लेकिन अगर आप दो मनमाने मूल्यों का उपयोग कर रहे हैं, तो एक इनलाइन का उपयोग करें if:

toggle = 'a' if toggle == 'b' else 'b'

1
+1 लेकिन toggle = 0 if toggle else 1छोटे और अधिक सामान्य है
ल्यूक

क्षमा करें, मैं इसे स्पष्ट करने के लिए चर स्वैप करूंगा। मैं ifदो मनमाने ढंग से चर के बीच इनलाइन टॉगल का उपयोग कर रहा था , न कि सिर्फ 1और सिर्फ 0
ब्लेंडर

14

सिर्फ 1 और 0 के बीच, ऐसा करें

1-x 

x 1 या 0 ले सकता है


के बाद से (पायथन 2.x में, वैसे भी) Trueऔर Falseवास्तव में पूर्णांक, एक आश्चर्यजनक रूप से अत्यधिक शब्द के साथ कर रहे हैं लोगों को यद्यपि __str__()विधि, xभी हो सकता है Trueया Falseयहाँ। आपको 1 या 0 वापस मिल जाएगा, हालांकि।
किंडल

12

त्रिकोणमितीय दृष्टिकोण , सिर्फ इसलिए sinऔर cosकार्य शांत हैं।

यहाँ छवि विवरण दर्ज करें

>>> import math
>>> def generator01():
...     n=0
...     while True:
...         yield abs( int( math.cos( n * 0.5 * math.pi  ) ) )
...         n+=1
... 
>>> g=generator01() 
>>> g.next()
1
>>> g.next()
0
>>> g.next()
1
>>> g.next()
0

हे भगवान! मैं <3 तुम।
ऋषभ अग्रहरी


7

आश्चर्यजनक रूप से अच्छे पुराने विभाजन का कोई उल्लेख नहीं करता है 2:

In : x = (x + 1)  % 2 ; x
Out: 1

In : x = (x + 1)  % 2 ; x
Out: 0

In : x = (x + 1)  % 2 ; x
Out: 1

In : x = (x + 1)  % 2 ; x
Out: 0

ध्यान दें कि यह बराबर है x = x - 1 , लेकिन मॉडुलो तकनीक का लाभ यह है कि समूह का आकार या अंतराल की लंबाई बड़ी हो सकती है, तो बस 2 तत्व, इस प्रकार आपको लूप ओवर करने के लिए राउंड-रॉबिन इंटरलेविंग योजना के समान है।

अब सिर्फ 2 के लिए, टॉगल करना थोड़ा कम हो सकता है (बिट-वार ऑपरेटर का उपयोग करके):

x = x ^ 1

मुझे यकीन नहीं है कि "पायथोनिक" यह कैसे (सी-लाइक) मोडुलो अंकगणित (i, e, क्या "पायथोनिक" लागू होता है?)। मुझे लगता है कि यह सिर्फ अंकगणित है, हर जगह काम करता है जहां आपके पास बाइनरी है।
योहान याकिमोविच

स्पष्ट रूप से एक्स = (1,2,3,0) जैसे टपल के साथ परिमित-राज्य-मशीन; टोकन = 0; टोकन = एक्स [टोकन] बेहद रोमांचक है, क्योंकि यह सिर्फ समूह संचालन से भी अधिक सामान्य हो सकता है।
योहान याकिमोविच

7

टॉगल करने का एक तरीका एकाधिक असाइनमेंट का उपयोग करना है

>>> a = 5
>>> b = 3

>>> t = a, b = b, a
>>> t[0]
3

>>> t = a, b = b, a
>>> t[0]
5

Itertools का उपयोग करना:

In [12]: foo = itertools.cycle([1, 2, 3])

In [13]: next(foo)
Out[13]: 1

In [14]: next(foo)
Out[14]: 2

In [15]: next(foo)
Out[15]: 3

In [16]: next(foo)
Out[16]: 1

In [17]: next(foo)
Out[17]: 2

4

1 और 0 के बीच टॉगल करने का सबसे आसान तरीका 1 से घटाना है।

def toggle(value):
    return 1 - value

4

अपवाद हैंडलर का उपयोग करना

>>> def toogle(x):
...     try:
...         return x/x-x/x
...     except  ZeroDivisionError:
...         return 1
... 
>>> x=0
>>> x=toogle(x)
>>> x
1
>>> x=toogle(x)
>>> x
0
>>> x=toogle(x)
>>> x
1
>>> x=toogle(x)
>>> x
0

ठीक है, मैं सबसे बुरा हूँ:

यहाँ छवि विवरण दर्ज करें

import math
import sys

d={1:0,0:1}
l=[1,0]

def exception_approach(x):
    try:
        return x/x-x/x
    except  ZeroDivisionError:
        return 1

def cosinus_approach(x):
    return abs( int( math.cos( x * 0.5 * math.pi  ) ) )

def module_approach(x):
    return  (x + 1)  % 2

def subs_approach(x):
    return  x - 1

def if_approach(x):
    return 0 if x == 1 else 1

def list_approach(x):
    global l
    return l[x]

def dict_approach(x):
    global d
    return d[x]

def xor_approach(x):
    return x^1

def not_approach(x):
    b=bool(x)
    p=not b
    return int(p)

funcs=[ exception_approach, cosinus_approach, dict_approach, module_approach, subs_approach, if_approach, list_approach, xor_approach, not_approach ]

f=funcs[int(sys.argv[1])]
print "\n\n\n", f.func_name
x=0
for _ in range(0,100000000):
    x=f(x)

3

कैसे एक काल्पनिक टॉगल के बारे में जो न केवल वर्तमान टॉगल को स्टोर करता है, बल्कि इसके साथ जुड़े कुछ अन्य मूल्य हैं?

toggle = complex.conjugate

किसी भी + या - बाईं ओर मान, और दाईं ओर कोई भी अहस्ताक्षरित मूल्य संग्रहीत करें:

>>> x = 2 - 3j
>>> toggle(x)
(2+3j)

शून्य काम करता है, भी:

>>> y = -2 - 0j
>>> toggle(y)
(-2+0j)

आसानी से वर्तमान टॉगल मान प्राप्त करें ( Trueऔर Falseप्रतिनिधित्व करें + और -), LHS (वास्तविक) मान, या RHS (इमेजिनरी) मान:

>>> import math
>>> curr = lambda i: math.atan2(i.imag, -abs(i.imag)) > 0
>>> lhs = lambda i: i.real
>>> rhs = lambda i: abs(i.imag)
>>> x = toggle(x)
>>> curr(x)
True
>>> lhs(x)
2.0
>>> rhs(x)
3.0

आसानी से LHS और RHS स्वैप करें (लेकिन ध्यान दें कि दोनों मानों का संकेत महत्वपूर्ण नहीं होना चाहिए):

>>> swap = lambda i: i/-1j
>>> swap(2+0j)
2j
>>> swap(3+2j)
(2+3j)

आसानी से एलएचएस और आरएचएस स्वैप करें और एक ही समय में भी टॉगल करें:

>>> swaggle = lambda i: i/1j
>>> swaggle(2+0j)
-2j
>>> swaggle(3+2j)
(2-3j)

त्रुटियों के खिलाफ गार्ड:

>>> toggle(1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: descriptor 'conjugate' requires a 'complex' object but received a 'int'

LHS और RHS में परिवर्तन करें:

>>> x += 1+2j
>>> x
(3+5j)

... लेकिन आरएचएस में हेरफेर करने वाले सावधान रहें:

>>> z = 1-1j
>>> z += 2j
>>> z
(1+1j) # whoops! toggled it!

2

चर और बी किसी भी दो मूल्य हो सकते हैं, जैसे 0 और 1, या 117 और 711, या "सिर" और "पूंछ"। कोई गणित का उपयोग नहीं किया जाता है, हर बार टॉगल वांछित होने पर हर बार मूल्यों का एक त्वरित स्वैप।

a = True   
b = False   

a,b = b,a   # a is now False
a,b = b,a   # a is now True

1

मैं एब्स फ़ंक्शन का उपयोग करता हूं, छोरों पर बहुत उपयोगी है

x = 1
for y in range(0, 3):
    x = abs(x - 1)

x 0 होगा।


0

चलो कुछ फ्रेम हैकिंग करते हैं। नाम से एक चर टॉगल करें। नोट: यह हर पायथन रनटाइम के साथ काम नहीं कर सकता है।

कहें कि आपके पास एक चर "x" है

>>> import inspect
>>> def toggle(var_name):
>>>     frame = inspect.currentframe().f_back
>>>     vars = frame.f_locals
>>>     vars[var_name] = 0 if vars[var_name] == 1 else 1

>>> x = 0
>>> toggle('x')
>>> x
1
>>> toggle('x')
>>> x
0

0

यदि आप एक पूर्णांक चर के साथ काम कर रहे हैं, तो आप 1 बढ़ा सकते हैं और अपने सेट को 0 और 1 (मॉड) तक सीमित कर सकते हैं

X = 0  # or X = 1
X = (X + 1)%2

0

-1 और +1 के बीच स्विचिंग को इनलाइन गुणा से प्राप्त किया जा सकता है; पी 'लीनिज़' (या इसी तरह) की गणना के लिए उपयोग किया जाता है:

sign = 1
result = 0
for i in range(100000):
    result += 1 / (2*i + 1) * sign
    sign *= -1
print("pi (estimate): ", result*4)

0

आप एस indexका उपयोग कर सकते हैं list

def toggleValues(values, currentValue):
    return values[(values.index(currentValue) + 1) % len(values)]

> toggleValues( [0,1] , 1 )
> 0
> toggleValues( ["one","two","three"] , "one" )
> "two"
> toggleValues( ["one","two","three"] , "three")
> "one"

पेशेवरों : कोई अतिरिक्त पुस्तकालयों, स्व.एक्सप्लैनेटरी कोड और मनमाने डेटा प्रकारों के साथ काम करना।

विपक्ष : डुप्लिकेट-सेव नहीं। toggleValues(["one","two","duped", "three", "duped", "four"], "duped") हमेशा लौटेगा"three"

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