Cách hiệu quả nhất để chuyển đổi giữa 0và là 1gì?
Cách hiệu quả nhất để chuyển đổi giữa 0và là 1gì?
Câu trả lời:
Nếu các giá trị là boolean, cách tiếp cận nhanh nhất là sử dụng toán tử không :
>>> x = True
>>> x = not x # toggle
>>> x
False
>>> x = not x # toggle
>>> x
True
>>> x = not x # toggle
>>> x
False
Nếu các giá trị là số, thì phép trừ khỏi tổng là một cách đơn giản và nhanh chóng để chuyển đổi các giá trị:
>>> 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
Nếu giá trị chuyển đổi trong khoảng từ 0 đến 1 , bạn có thể sử dụng độc quyền bitwise-hoặc :
>>> x = 1
>>> x ^= 1
>>> x
0
>>> x ^= 1
>>> x
1
Kỹ thuật này khái quát cho bất kỳ cặp số nguyên nào. Bước xor-by-one được thay thế bằng hằng số xor-by-preomputing-Constant:
>>> 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
(Ý tưởng này đã được gửi bởi Nick Coghlan và sau đó được khái quát bởi @zxxc.)
Nếu các giá trị có thể băm, bạn có thể sử dụng từ điển:
>>> 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'
Cách chậm nhất là sử dụng biểu thức điều kiện :
>>> 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]
Nếu bạn có nhiều hơn hai giá trị, hàm itertools. Motorcycle () cung cấp một cách nhanh chóng chung để chuyển đổi giữa các giá trị liên tiếp:
>>> import itertools
>>> toggle = itertools.cycle(['red', 'green', 'blue']).next
>>> toggle()
'red'
>>> toggle()
'green'
>>> toggle()
'blue'
>>> toggle()
'red'
>>> toggle()
'green'
>>> toggle()
'blue'
Lưu ý rằng trong Python 3 next()phương thức đã được thay đổi thành __next__(), vì vậy dòng đầu tiên sẽ được viết làtoggle = itertools.cycle(['red', 'green', 'blue']).__next__
.next()đã được thay thế bằng next()hàm toàn cục . Ví dụ trên sẽ là:toggle = itertools.cycle(...); next(toggle)
toggle = itertools.cycle(['red', 'green', 'blue']) next(toggle)
avà bsử dụng x = x ^ (a ^ b).
int(not 0)và int(not 1)... hrmmm
Tôi luôn luôn sử dụng:
p^=True
Nếu p là boolean, điều này sẽ chuyển giữa đúng và sai.
pkhông cần phải tham khảo hai lần để phương pháp này hoạt động !! Ý tưởng nếu bạn đang thay đổi một giá trị với một tài liệu tham khảo dài.
^=là giả định xor bitwise
Đây là một cách không trực quan khác. Vẻ đẹp là bạn có thể xoay vòng qua nhiều giá trị và không chỉ hai [0,1]
Cho hai giá trị (chuyển đổi)
>>> x=[1,0]
>>> toggle=x[toggle]
Đối với nhiều giá trị (nói 4)
>>> x=[1,2,3,0]
>>> toggle=x[toggle]
Tôi không mong đợi giải pháp này cũng gần như nhanh nhất
>>> 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
Các notnhà điều hành phủ nhận biến của bạn (chuyển đổi nó thành một boolean nếu nó chưa được một). Bạn có thể có thể sử dụng 1và 0hoán đổi cho nhau Truevà Falsevì vậy chỉ cần phủ nhận nó:
toggle = not toggle
Nhưng nếu bạn đang sử dụng hai giá trị tùy ý, hãy sử dụng một dòng if:
toggle = 'a' if toggle == 'b' else 'b'
toggle = 0 if toggle else 1là ngắn hơn và tổng quát hơn
ifđể chuyển đổi giữa hai biến tùy ý , không chỉ 1và 0.
Chỉ từ 1 đến 0, làm điều này
1-x
x có thể mất 1 hoặc 0
Truevà Falsethực sự là các số nguyên, mặc dù các số có __str__()phương thức dài dòng đáng ngạc nhiên , xcũng có thể Truehoặc Falseở đây. Bạn sẽ nhận được 1 hoặc 0 trở lại, mặc dù.
Phương pháp lượng giác , chỉ vì sinvà các coschức năng là mát mẻ.
>>> 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
Đáng ngạc nhiên không ai đề cập đến modulo phân chia cũ 2 tốt:
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
Lưu ý rằng nó tương đương với x = x - 1, nhưng lợi thế của kỹ thuật modulo là kích thước của nhóm hoặc độ dài của khoảng có thể lớn hơn chỉ bằng 2 phần tử, do đó cung cấp cho bạn một sơ đồ xen kẽ vòng tròn để lặp lại.
Bây giờ chỉ với 2, việc chuyển đổi có thể ngắn hơn một chút (sử dụng toán tử bit-khôn ngoan):
x = x ^ 1
một cách để chuyển đổi là sử dụng nhiều bài tập
>>> a = 5
>>> b = 3
>>> t = a, b = b, a
>>> t[0]
3
>>> t = a, b = b, a
>>> t[0]
5
Sử dụng 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
Sử dụng xử lý ngoại lệ
>>> 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
Ok, tôi là người tồi tệ nhất:
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)
Làm thế nào về một chuyển đổi tưởng tượng lưu trữ không chỉ chuyển đổi hiện tại, mà một vài giá trị khác liên quan đến nó?
toggle = complex.conjugate
Lưu trữ bất kỳ giá trị + hoặc - ở bên trái và bất kỳ giá trị không dấu nào ở bên phải:
>>> x = 2 - 3j
>>> toggle(x)
(2+3j)
Không hoạt động, quá:
>>> y = -2 - 0j
>>> toggle(y)
(-2+0j)
Dễ dàng truy xuất giá trị chuyển đổi hiện tại ( Truevà Falseđại diện cho giá trị + và -), giá trị LHS (thực) hoặc RHS (tưởng tượng):
>>> 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
Dễ dàng trao đổi LHS và RHS (nhưng lưu ý rằng dấu hiệu của cả hai giá trị không phải là quan trọng):
>>> swap = lambda i: i/-1j
>>> swap(2+0j)
2j
>>> swap(3+2j)
(2+3j)
Dễ dàng trao đổi LHS và RHS và cũng có thể chuyển đổi cùng một lúc:
>>> swaggle = lambda i: i/1j
>>> swaggle(2+0j)
-2j
>>> swaggle(3+2j)
(2-3j)
Bảo vệ chống lại lỗi:
>>> toggle(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: descriptor 'conjugate' requires a 'complex' object but received a 'int'
Thực hiện các thay đổi đối với LHS và RHS:
>>> x += 1+2j
>>> x
(3+5j)
... nhưng hãy cẩn thận thao túng RHS:
>>> z = 1-1j
>>> z += 2j
>>> z
(1+1j) # whoops! toggled it!
Các biến a và b có thể là BẤT K Two hai giá trị, như 0 và 1, hoặc 117 và 711 hoặc "đầu" và "đuôi". Không có toán học nào được sử dụng, chỉ cần trao đổi nhanh các giá trị mỗi khi muốn chuyển đổi.
a = True
b = False
a,b = b,a # a is now False
a,b = b,a # a is now True
Hãy thực hiện một số hack khung. Chuyển đổi một biến theo tên. Lưu ý: Điều này có thể không hoạt động với mọi thời gian chạy Python.
Giả sử bạn có một biến "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
Nếu bạn đang xử lý một biến số nguyên, bạn có thể tăng 1 và giới hạn cài đặt của mình thành 0 và 1 (mod)
X = 0 # or X = 1
X = (X + 1)%2
Chuyển đổi giữa -1 và +1 có thể thu được bằng cách nhân nội tuyến; được sử dụng để tính pi theo cách 'Leibniz' (hoặc tương tự):
sign = 1
result = 0
for i in range(100000):
result += 1 / (2*i + 1) * sign
sign *= -1
print("pi (estimate): ", result*4)
Bạn có thể sử dụng indexcủa lists.
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"
Ưu điểm : Không có thư viện bổ sung, mã self.explanatory và làm việc với các loại dữ liệu tùy ý.
Nhược điểm : không trùng lặp-lưu.
toggleValues(["one","two","duped", "three", "duped", "four"], "duped")
sẽ luôn trở lại"three"