2009-11-22 37 views
17

Trong một số phần của chương trình Python, tôi có biến val có thể là 1 hoặc 0. Nếu 1 tôi phải đổi thành 0, nếu bằng 0, tôi phải thay đổi thành 1.Hoán đổi 1 với 0 và 0 với 1 theo cách Pythonic

Làm thế nào để bạn thực hiện nó theo cách Pythonic?

if val == 1: 
    val = 0 
elif val == 0: 
    val = 1 

quá dài!

tôi đã làm:

swap = {0: 1, 1:0} 

Vì vậy, tôi có thể sử dụng nó:

swap[val] 

ý tưởng khác?

+6

Có một lý do không sử dụng 'TRUE' /' FALSE' thay vì '1'/'0' trong trường hợp của bạn? – jfs

+2

Cách Pythonic nhất để làm điều này sẽ đưa vào tài khoản ý nghĩa của biến. Nó có số không? Boolean (tức là True/False)? Liệu nó có một số ý nghĩa ngữ nghĩa không rõ ràng ở đây? Thực tế là bạn muốn chuyển đổi nó ngụ ý rằng nó có một số ý nghĩa ... nó là gì? –

+0

Tôi nghĩ cụm từ bạn đang tìm kiếm là "chuyển đổi". –

Trả lời

91

Đây không phải là pythonic, nhưng nó là ngôn ngữ trung lập. Thường thì val = 1 - val là đơn giản nhất.

+28

Đó là quá dễ đọc! Đi cho 'val^= 1'! – abyx

+7

Đó là thông minh, nhưng nó đòi hỏi người đọc mã của bạn để suy nghĩ (có thể), có thể buộc bạn phải thêm một bình luận. Tôi thích ternary tốt hơn ví dụ. val = 0 nếu val khác 1 bởi vì nó nói chính xác những gì nó làm. – rplevy

+2

Một cách khác để nói cùng một điều: var = ((var + 1) & 1). – MAK

20

Kể từ True == 1False == 0 trong python,

bạn chỉ có thể sử dụng var = not var

Nó sẽ chỉ trao đổi nó.

+0

không 1 == Sai, không phải 0 == Đúng –

+0

Điều này có vẻ như là một chi tiết triển khai và không thể dựa vào nó. –

+0

nhưng 'int (không 1) == 0' và' int (không 0) == 1' vì 'int (True) == 1' và' int (False) == 0'. và điều này có thể không phải là chi tiết triển khai. –

1

Nếu bạn muốn trở thành ngắn:

f = lambda val: 0 if val else 1 

Sau đó:

>>> f(0) 
1 
>>> f(1) 
0 
5

Trong trường hợp của bạn tôi khuyên bạn nên ternary:

val = 0 if val else 1 

Nếu bạn đã có 2 biến để trao đổi bạn có thể nói:

(a, b) = (b, a) 
+0

OP không có hai giá trị để hoán đổi. anh ta có một giá trị duy nhất mà anh ấy muốn thay đổi – SilentGhost

+0

Đã thêm một chỉnh sửa. Ternary có ý nghĩa hơn ở đây. – rplevy

9

Chỉ cần một khả năng:

i = (1,0)[i] 

này hoạt động tốt miễn là tôi là tích cực, như dbr chỉ ra trong các ý kiến ​​nó không hoạt động thất bại cho tôi < 0.

Bạn có chắc chắn bạn không muốn sử dụng FalseTrue? Nghe có vẻ gần như vậy.

+0

Nó sẽ không lỗi nếu 'i' là' -1' hoặc '-2', và sẽ hành động kỳ lạ. '{0: 1, 1: 0} [i]' sẽ lỗi tuy nhiên – dbr

+0

@dbr cảm ơn. Tôi muốn bao gồm điều này trong câu trả lời, nhưng sau đó tôi thấy rằng OP đã tìm thấy câu trả lời này. Tôi gắn bó với cái tôi có bởi vì nó rất nhỏ gọn. –

12

Cách tiếp cận ngắn nhất là sử dụng toán tử XOR bitwise.

Nếu bạn muốn val để được bố trí:

val ^= 1 

Nếu bạn không muốn val để được bố trí:

val^1 
+0

Tôi thích câu trả lời này bởi vì nó cung cấp cơ hội để thực hiện hoán đổi động, sử dụng "'^1' "hoặc" '^ 0'", sau đó không chuyển đổi. –

0

Chức năng với lập luận có thể thay đổi. Gọi số swaper() sẽ trả về giá trị khác nhau mỗi lần.

def swaper(x=[1]): 
    x[0] ^= 1 
    return x[0] 
0

Chỉ cần một cách khác:

val = ~val + 2 
1

(0,1) [không val] flips các val 0-1 và ngược lại.

+0

['không val'] (http://stackoverflow.com/a/1779305/4279) * tự nó * lật val từ' 0' sang '1'. Lưu ý: 'False == 0' và' 1 == True' trong Python. – jfs

1

Để mở rộng khi answer by "YOU", sử dụng:

int(not(val)) 

Ví dụ:

>>> val = 0 
>>> int(not(val)) 
1 
>>> val = 1 
>>> int(not(val)) 
0 

Lưu ý rằng câu trả lời này chỉ có nghĩa là để được mô tả, không quy tắc.

0

Cách của bạn hoạt động tốt!

gì về:

val = abs(val - 1) 

ngắn và đơn giản!

0

Cách pythonic nhất có lẽ sẽ là

int(not val) 

Nhưng một cách ngắn hơn sẽ

-~-val 
Các vấn đề liên quan