Python có một toán tử điều kiện ternary?


6046

Nếu Python không có toán tử điều kiện ternary, có thể mô phỏng một toán tử bằng các cấu trúc ngôn ngữ khác không?


149
Trong tài liệu chính thức của Python 3.0 được tham chiếu trong một nhận xét ở trên, điều này được gọi là "điều kiện_expressions" và được xác định rất mật mã. Tài liệu đó thậm chí không bao gồm thuật ngữ "ternary", vì vậy bạn sẽ khó tìm thấy nó qua Google trừ khi bạn biết chính xác những gì cần tìm. Các tài liệu phiên bản 2 là phần nào hữu ích hơn và bao gồm một liên kết đến "PEP 308" , trong đó bao gồm rất nhiều bối cảnh lịch sử thú vị liên quan đến câu hỏi này.
tộc

26
"ternary" (có ba đầu vào) là một thuộc tính hệ quả của sự không phù hợp này, không phải là một thuộc tính xác định của khái niệm này. ví dụ: SQL có case [...] { when ... then ...} [ else ... ] endmột hiệu ứng tương tự nhưng hoàn toàn không phải là ternary.
dùng313114

10
còn ISO / IEC 9899 (tiêu chuẩn ngôn ngữ lập trình C) phần 6.5.15 gọi nó là "toán tử điều kiện"
user313114

9
Wikipedia bao quát điều này trong bài viết " ?: ".
HelloGoodbye

9
Trong những năm kể từ khi bình luận của quý tộc, tài liệu biểu thức điều kiện đã được cập nhật để nói các biểu thức có điều kiện (đôi khi được gọi là toán tử ternary
Scott Martin

Câu trả lời:


7044

Có, nó đã được thêm vào trong phiên bản 2.5. Cú pháp biểu thức là:

a if condition else b

Đầu tiên conditionđược đánh giá, sau đó chính xác một trong hai ahoặc bđược đánh giá và trả về dựa trên giá trị Boolean của condition. Nếu conditionđánh giá True, sau đó ađược đánh giá và trả về nhưng bbị bỏ qua, hoặc nếu không bđược đánh giá và trả lại nhưng abị bỏ qua.

Điều này cho phép đoản mạch vì khi nào conditionđúng chỉ ađược đánh giá và hoàn toàn bkhông được đánh giá, nhưng khi nào conditionsai chỉ bđược đánh giá và hoàn toàn akhông được đánh giá.

Ví dụ:

>>> 'true' if True else 'false'
'true'
>>> 'true' if False else 'false'
'false'

Lưu ý rằng các điều kiện là một biểu thức , không phải là một tuyên bố . Điều này có nghĩa là bạn không thể sử dụng câu lệnh gán hoặc passhoặc câu lệnh khác trong biểu thức điều kiện :

>>> pass if False else x = 3
  File "<stdin>", line 1
    pass if False else x = 3
          ^
SyntaxError: invalid syntax

Tuy nhiên, bạn có thể sử dụng các biểu thức điều kiện để gán một biến như vậy:

x = a if True else b

Hãy nghĩ về biểu thức điều kiện như chuyển đổi giữa hai giá trị. Nó rất hữu ích khi bạn ở trong tình huống 'một giá trị này hoặc một giá trị khác', nhưng nó không làm được gì nhiều.

Nếu bạn cần sử dụng các câu lệnh, bạn phải sử dụng một if câu lệnh bình thường thay vì một biểu thức điều kiện .


Hãy nhớ rằng nó bị một số Pythonistas cau mày vì một số lý do:

  • Thứ tự của các đối số khác với các condition ? a : btoán tử ternary cổ điển từ nhiều ngôn ngữ khác (như C, C ++, Go, Perl, Ruby, Java, Javascript, v.v.), có thể dẫn đến lỗi khi mọi người không quen với Python " đáng ngạc nhiên "hành vi sử dụng nó (họ có thể đảo ngược thứ tự đối số).
  • Một số người thấy nó "khó sử dụng", vì nó đi ngược lại với dòng suy nghĩ thông thường (nghĩ về điều kiện trước và sau đó là các hiệu ứng).
  • Lý do phong cách. (Mặc dù 'nội tuyến if' có thể thực sự hữu ích và làm cho tập lệnh của bạn ngắn gọn hơn, nhưng nó thực sự làm phức tạp mã của bạn)

Nếu bạn gặp khó khăn trong việc ghi nhớ thứ tự, thì hãy nhớ rằng khi đọc to, bạn (gần như) nói ý của bạn. Ví dụ, x = 4 if b > 8 else 9được đọc to như x will be 4 if b is greater than 8 otherwise 9.

Tài liệu chính thức:


269
Trật tự có vẻ lạ đối với các lập trình viên tuy nhiên f(x) = |x| = x if x > 0 else -xnghe có vẻ rất tự nhiên đối với các nhà toán học. Bạn cũng có thể hiểu nó giống như làm A trong hầu hết các trường hợp, ngoại trừ khi C thì bạn nên làm B thay vì ...
yota

121
Hãy cẩn thận với thứ tự các hoạt động khi sử dụng này. Ví dụ, dòng z = 3 + x if x < y else y. Nếu x=2y=1, bạn có thể mong đợi rằng mang lại 4, nhưng nó thực sự mang lại 1. z = 3 + (x if x > y else y)là cách sử dụng đúng.
Kal Zekdor 6/03/2016

11
Vấn đề là nếu bạn muốn thực hiện các đánh giá bổ sung sau khi đánh giá điều kiện, như thêm giá trị vào kết quả, bạn sẽ cần thêm biểu thức bổ sung cho cả hai bên ( z = 3 + x if x < y else 3 + y) hoặc nhóm điều kiện ( z = 3 + (x if x < y else y)hoặc z = (x if x < y else y) + 3)
Kal Zekdor

4
@MrGeek, tôi hiểu ý của bạn, vì vậy về cơ bản bạn sẽ lồng các hoạt động: `" foo "nếu Bool khác (" bar "nếu Bool khác" foobar ")`
Dimesio

3
Các lập trình viên cần công thức chính xác chính xác thậm chí nhiều hơn nhà toán học, bởi vì trong toán học luôn có một khái niệm cơ bản. Một lập luận thuyết phục là toán tử%, bắt chước cách "mod" được sử dụng trong toán học sẽ là một thảm họa. Vì vậy, không, tôi không chấp nhận lập luận của bạn. Nó giống như tuân thủ các đơn vị đế quốc. Groetjes Albert
Albert van der Horst

798

Bạn có thể lập chỉ mục thành một tuple:

(falseValue, trueValue)[test]

testcần trả về Đúng hay Sai .
Có thể an toàn hơn khi luôn thực hiện nó như sau:

(falseValue, trueValue)[test == True]

hoặc bạn có thể sử dụng tích hợp bool()để đảm bảo giá trị Boolean :

(falseValue, trueValue)[bool(<expression>)]

590
Lưu ý rằng cái này luôn đánh giá mọi thứ, trong khi cấu trúc if / other chỉ đánh giá biểu thức chiến thắng.
SilverbackNet

117
(lambda: print("a"), lambda: print("b"))[test==true]()
Dustin Getz

15
Cần lưu ý rằng những gì trong []s có thể là một biểu thức tùy ý. Ngoài ra, để an toàn, bạn có thể kiểm tra tính trung thực bằng cách viết [bool(<expression>)]. Các bool()chức năng đã được khoảng từ v2.2.1.
martineau

12
Tôi đã thực hiện một mẹo tương tự - chỉ một hoặc hai lần, nhưng đã thực hiện nó - bằng cách lập chỉ mục vào một từ điển với TrueFalsenhư các khóa: {True:trueValue, False:falseValue}[test] Tôi không biết liệu điều này có kém hiệu quả hơn không, nhưng ít nhất nó cũng tránh được toàn bộ Cuộc tranh luận "thanh lịch" so với "xấu xí". Không có sự mơ hồ rằng bạn đang đối phó với một boolean hơn là một int.
JDM


338

Đối với các phiên bản trước 2.5, có mẹo:

[expression] and [on_true] or [on_false]

Nó có thể cho kết quả sai khi on_true có giá trị boolean sai. 1
Mặc dù nó có lợi ích trong việc đánh giá các biểu thức từ trái sang phải, nhưng theo tôi thì rõ ràng hơn.

1. Có tương đương với C's không?: Toán tử ternary?


67
Biện pháp khắc phục là sử dụng (kiểm tra và [true_value] hoặc [false_value]) [0], để tránh bẫy này.
ThomasH

5
Toán tử ternary thường thực thi nhanh hơn (đôi khi 10-25%).
núi lửa

7
@volcano Bạn có nguồn nào cho tôi không?
OrangeTux

4
@OrangeTux Đây là mã được tháo rời . Sử dụng phương pháp ThomasH đề xuất sẽ còn chậm hơn.
mbomb007

265

<expression 1> if <condition> else <expression 2>

a = 1
b = 2

1 if a > b else -1 
# Output is -1

1 if a > b else -1 if a < b else 0
# Output is -1

83
Điều này nhấn mạnh mục đích chính của toán tử ternary: lựa chọn giá trị. Nó cũng cho thấy rằng nhiều hơn một con chim nhạn có thể được xích lại với nhau thành một biểu thức duy nhất.
Roy Tinker

6
@Craig, tôi đồng ý, nhưng cũng hữu ích để biết điều gì sẽ xảy ra khi không có dấu ngoặc đơn. Trong mã thực, tôi cũng có xu hướng chèn parens rõ ràng.
Jon Coombs

159

Từ tài liệu :

Các biểu thức có điều kiện (đôi khi được gọi là toán tử ba chiều của người Viking) có mức ưu tiên thấp nhất trong tất cả các hoạt động của Python.

Biểu thức x if C else yđầu tiên đánh giá điều kiện, C ( không phải x ); nếu C đúng, x được ước tính và giá trị của nó được trả về; mặt khác, y được ước tính và giá trị của nó được trả về.

Xem PEP 308 để biết thêm chi tiết về các biểu thức điều kiện.

Mới kể từ phiên bản 2.5.


120

Một toán tử cho một biểu thức có điều kiện trong Python đã được thêm vào năm 2006 như là một phần của Đề xuất nâng cao Python 308 . Hình thức của nó khác với ?:toán tử thông thường và nó:

<expression1> if <condition> else <expression2>

tương đương với:

if <condition>: <expression1> else: <expression2>

Đây là một ví dụ:

result = x if a > b else y

Một cú pháp khác có thể được sử dụng (tương thích với các phiên bản trước 2.5):

result = (lambda:y, lambda:x)[a > b]()

trong đó toán hạng được đánh giá lười biếng .

Một cách khác là lập chỉ mục một tuple (không phù hợp với toán tử điều kiện của hầu hết các ngôn ngữ khác):

result = (y, x)[a > b]

hoặc từ điển được xây dựng rõ ràng:

result = {True: x, False: y}[a > b]

Một phương pháp khác (ít đáng tin cậy hơn), nhưng đơn giản hơn là sử dụng andortoán tử:

result = (a > b) and x or y

tuy nhiên điều này sẽ không hoạt động nếu xcó thể False.

Một cách giải quyết khác có thể là tạo xyliệt kê hoặc bộ dữ liệu như sau:

result = ((a > b) and [x] or [y])[0]

hoặc là:

result = ((a > b) and (x,) or (y,))[0]

Nếu bạn đang làm việc với từ điển, thay vì sử dụng một điều kiện ternary, bạn có thể tận dụng get(key, default), ví dụ:

shell = os.environ.get('SHELL', "/bin/sh")

Nguồn: ?: Trong Python tại Wikipedia


1
result = {1: x, 0: y}[a > b]là một biến thể có thể khác ( TrueFalsethực sự là số nguyên với các giá trị 10)
Walter Tross

98

thật không may

(falseValue, trueValue)[test]

giải pháp không có hành vi ngắn mạch; do đó cả hai falseValuetrueValueđược đánh giá bất kể điều kiện. Đây có thể là tối ưu hoặc thậm chí là lỗi (tức là cả hai trueValuefalseValuecó thể là phương pháp và có tác dụng phụ).

Một giải pháp cho vấn đề này là

(lambda: falseValue, lambda: trueValue)[test]()

(thực thi bị trì hoãn cho đến khi người chiến thắng được biết;)), nhưng nó đưa ra sự không nhất quán giữa các đối tượng có thể gọi và không thể gọi được. Ngoài ra, nó không giải quyết trường hợp khi sử dụng thuộc tính.

Và câu chuyện đã xảy ra - lựa chọn giữa 3 giải pháp được đề cập là sự đánh đổi giữa việc có tính năng ngắn mạch, sử dụng ít nhất Зython 2.5 (IMHO không phải là vấn đề nữa) và không dễ bị lỗi " trueValue-đánh giá thành sai" .


2
Trong khi bộ lừa lambdas hoạt động, phải mất khoảng 3 lần so với toán tử ternary. Nó chỉ có thể là một ý tưởng hợp lý nếu nó có thể thay thế một chuỗi dài if else if.
Perkins

72

Toán tử Ternary trong các ngôn ngữ lập trình khác nhau

Ở đây tôi chỉ cố gắng thể hiện một số khác biệt quan trọng ternary operatorgiữa một vài ngôn ngữ lập trình.

Toán tử Ternary trong Javascript

var a = true ? 1 : 0;
# 1
var b = false ? 1 : 0;
# 0

Toán tử Ternary trong Ruby

a = true ? 1 : 0
# 1
b = false ? 1 : 0
# 0

Toán tử ternary ở Scala

val a = true ? 1 | 0
# 1
val b = false ? 1 | 0
# 0

Toán tử ternary trong lập trình R

a <- if (TRUE) 1 else 0
# 1
b <- if (FALSE) 1 else 0
# 0

Toán tử ternary trong Python

a = 1 if True else 0
# 1
b = 1 if False else 0
# 0


5
Nó có vẻ có ý kiến; nhưng điều cơ bản nói là cú pháp Python có thể được hiểu bởi một người chưa bao giờ nhìn thấy một toán tử ternary, trong khi rất ít người sẽ hiểu cú pháp thông thường hơn trừ khi họ được nói trước về ý nghĩa của nó.
fralau

1
Algol68: a = .if. .thật. .sau đó. 1 .else. 0 .fi. Điều này cũng có thể được biểu thị a = (. True. | 1 | 0) Như thường lệ Algol68 là một cải tiến so với những người kế nhiệm của nó.
Albert van der Horst

63

Đối với Python 2.5 và mới hơn có một cú pháp cụ thể:

[on_true] if [cond] else [on_false]

Ở Pythons cũ, một toán tử ternary không được triển khai nhưng có thể mô phỏng nó.

cond and on_true or on_false

Mặc dù, có một vấn đề tiềm ẩn, nếu condđánh giá Trueon_trueđánh giá Falsesau đó on_falseđược trả lại thay vì on_true. Nếu bạn muốn hành vi này phương thức là OK, nếu không hãy sử dụng:

{True: on_true, False: on_false}[cond is True] # is True, not == True

có thể được bọc bởi:

def q(cond, on_true, on_false)
    return {True: on_true, False: on_false}[cond is True]

và sử dụng theo cách này:

q(cond, on_true, on_false)

Nó tương thích với tất cả các phiên bản Python.


2
Hành vi không giống nhau - q("blob", on_true, on_false)trả về on_false, trong khi on_true if cond else on_falsetrả về on_true. Một cách giải quyết là để thay thế condvới cond is not Nonetrong những trường hợp này, mặc dù đó không phải là một giải pháp hoàn hảo.

5
Tại sao không bool(cond)thay thế cond is True? Cái trước kiểm tra tính trung thực của condcái sau, cái sau kiểm tra sự bằng nhau của con trỏ với Trueđối tượng. Như được nhấn mạnh bởi @AndrewCecil, "blob"là sự thật nhưng nó is not True.
Jonas Kölker

Wow, có vẻ rất hack! :) Về mặt kỹ thuật, bạn thậm chí có thể viết [on_false, on_True][cond is True]để biểu thức trở nên ngắn hơn.
Asen

Không có ngắn mạch trong câu trả lời này. Nếu on_true và on_false đắt tiền thì đây là một câu trả lời tồi.
Hucker

44

Bạn có thể thường xuyên tìm thấy

cond and on_true or on_false

nhưng điều này dẫn đến sự cố khi on_true == 0

>>> x = 0
>>> print x == 0 and 0 or 1 
1
>>> x = 1
>>> print x == 0 and 0 or 1 
1

nơi bạn mong đợi cho một nhà điều hành ternary bình thường kết quả này

>>> x = 0
>>> print 0 if x == 0 else 1 
0
>>> x = 1
>>> print 0 if x == 0 else 1 
1

38

Python có một toán tử điều kiện ternary?

Đúng. Từ tệp ngữ pháp :

test: or_test ['if' or_test 'else' test] | lambdef

Phần quan tâm là:

or_test ['if' or_test 'else' test]

Vì vậy, một hoạt động có điều kiện ternary có dạng:

expression1 if expression2 else expression3

expression3sẽ được đánh giá một cách lười biếng (nghĩa là chỉ được đánh giá nếu expression2sai trong bối cảnh boolean). Và vì định nghĩa đệ quy, bạn có thể xâu chuỗi chúng vô thời hạn (mặc dù nó có thể được coi là phong cách xấu.)

expression1 if expression2 else expression3 if expression4 else expression5 # and so on

Một lưu ý khi sử dụng:

Lưu ý rằng mỗi ifphải được theo sau với một else. Những người học hiểu danh sách và biểu thức trình tạo có thể thấy đây là một bài học khó học - những điều sau đây sẽ không hoạt động, vì Python mong đợi một biểu thức thứ ba cho một biểu thức khác:

[expression1 if expression2 for element in iterable]
#                          ^-- need an else here

mà tăng a SyntaxError: invalid syntax. Vì vậy, ở trên là một đoạn logic chưa hoàn chỉnh (có lẽ người dùng mong đợi không có op trong điều kiện sai) hoặc điều có thể được dự định là sử dụng biểu thức 2 làm bộ lọc - lưu ý rằng sau đây là Python hợp pháp:

[expression1 for element in iterable if expression2]

expression2hoạt động như một bộ lọc để hiểu danh sách, và không phải là một toán tử điều kiện ternary.

Cú pháp thay thế cho trường hợp hẹp hơn:

Bạn có thể thấy hơi đau khi viết như sau:

expression1 if expression1 else expression2

expression1sẽ phải được đánh giá hai lần với cách sử dụng ở trên. Nó có thể hạn chế sự dư thừa nếu nó chỉ đơn giản là một biến cục bộ. Tuy nhiên, một thành ngữ Pythonic phổ biến và hiệu quả cho trường hợp sử dụng này là sử dụng orhành vi rút gọn của:

expression1 or expression2

tương đương về ngữ nghĩa. Lưu ý rằng một số hướng dẫn kiểu có thể hạn chế việc sử dụng này với lý do rõ ràng - nó có rất nhiều ý nghĩa thành rất ít cú pháp.


1
expression1 or expression2tương tự và có cùng nhược điểm / tích cực như expression1 || expression2trong javascript
JSDBroughton

1
Cảm ơn, @selurvedu - nó có thể gây nhầm lẫn cho đến khi bạn nói thẳng. Tôi đã học một cách khó khăn, vì vậy cách của bạn có thể không khó như vậy. ;) Sử dụng nếu không có khác, ở cuối biểu thức trình tạo hoặc hiểu danh sách sẽ lọc lặp lại. Ở phía trước, nó là một hoạt động có điều kiện ternary, và yêu cầu khác. Chúc mừng !!
Aaron Hall

@AaronHall Mặc dù việc sử dụng metasyntactic expressionNcho tất cả các trường hợp là nhất quán, nhưng có thể dễ hiểu hơn với cách đặt tên phân biệt biểu thức kiểm tra có điều kiện với hai biểu thức kết quả; ví dụ result1 if condition else result2. Điều này đặc biệt rõ ràng khi làm tổ (còn gọi là chuỗi) : result1 if condition1 else result2 if condition2 else result3. Xem cách này tốt hơn bao nhiêu?
tchrist

@tchrist cảm ơn bạn đã xem xét - nếu bạn nhìn vào lịch sử sửa đổi, bài đăng này hiện có hai phiên bản. Hầu hết các câu trả lời khác của tôi, đặc biệt là những câu trả lời hàng đầu, đã được xem lại nhiều lần. Câu trả lời này không bao giờ nhận được sự chú ý của tôi vì trạng thái wiki cộng đồng không cho tôi tín dụng cho nội dung và vì vậy tôi không bao giờ thấy bất kỳ phiếu bầu nào trên đó. Vì tôi không thực sự có thời gian để chỉnh sửa điều này ngay bây giờ, ếch biết khi nào nó sẽ lại được tôi chú ý trong tương lai. Tôi có thể thấy bạn đã chỉnh sửa câu trả lời hàng đầu, vì vậy, vui lòng mượn / trích dẫn tài liệu của tôi từ bài đăng này trong bài đó (và trích dẫn tôi nếu apropos!)
Aaron Hall

23

Mô phỏng toán tử ternary python.

Ví dụ

a, b, x, y = 1, 2, 'a greather than b', 'b greater than a'
result = (lambda:y, lambda:x)[a > b]()

đầu ra:

'b greater than a'

Tại sao không đơn giản result = (y, x)[a < b]Tại sao bạn sử dụng lambdachức năng ?
Grijesh Chauhan 27/12/13

5
@GrijeshChauhan Bởi vì trên các biểu thức "đã được khiếu nại", ví dụ như liên quan đến một lệnh gọi hàm, v.v., điều này sẽ được thực thi trong cả hai trường hợp. Điều này có thể không muốn.
glglgl

20

Toán tử điều kiện ternary chỉ đơn giản cho phép kiểm tra một điều kiện trong một dòng duy nhất thay thế cho multiline if-other làm cho mã nhỏ gọn.

Cú pháp:

[on_true] nếu [biểu thức] khác [on_false]

1- Phương pháp đơn giản để sử dụng toán tử ternary:

# Program to demonstrate conditional operator
a, b = 10, 20
# Copy value of a in min if a < b else copy b
min = a if a < b else b
print(min)  # Output: 10

2- Phương pháp trực tiếp sử dụng bộ dữ liệu, từ điển và lambda:

# Python program to demonstrate ternary operator
a, b = 10, 20
# Use tuple for selecting an item
print( (b, a) [a < b] )
# Use Dictionary for selecting an item
print({True: a, False: b} [a < b])
# lamda is more efficient than above two methods
# because in lambda  we are assure that
# only one expression will be evaluated unlike in
# tuple and Dictionary
print((lambda: b, lambda: a)[a < b]()) # in output you should see three 10

3- Toán tử ternary có thể được viết là lồng nhau nếu-khác:

# Python program to demonstrate nested ternary operator
a, b = 10, 20
print ("Both a and b are equal" if a == b else "a is greater than b"
        if a > b else "b is greater than a")

Cách tiếp cận trên có thể được viết là:

# Python program to demonstrate nested ternary operator
a, b = 10, 20
if a != b:
    if a > b:
        print("a is greater than b")
    else:
        print("b is greater than a")
else:
    print("Both a and b are equal") 
# Output: b is greater than a

1
Lưu ý rằng toán tử ternary nhỏ hơn (trong bộ nhớ) và nhanh hơn so với if lồng nhau. Ngoài ra, lồng nhau của bạn if-elsekhông thực sự là một bản viết lại của toán tử ternary và sẽ tạo ra đầu ra khác nhau cho các giá trị được chọn của a và b (cụ thể nếu một loại là một __ne__phương thức thực hiện một phương thức kỳ lạ ).
Perkins

19

bạn có thể làm được việc này :-

[condition] and [expression_1] or [expression_2] ;

Thí dụ:-

print(number%2 and "odd" or "even")

Điều này sẽ in "lẻ" nếu số là số lẻ hoặc "chẵn" nếu số đó là số chẵn.


Kết quả: - Nếu điều kiện là exp_1 đúng được thực thi thì exp_2 được thực thi.

Lưu ý: - 0, Không có, Sai, danh sách trống, blankString đánh giá là Sai. Và bất kỳ dữ liệu nào khác 0 đều đánh giá là True.

Đây là cách nó hoạt động:

nếu điều kiện [điều kiện] trở thành "Đúng" thì biểu thức_1 sẽ được ước tính nhưng không phải là biểu thức_2. Nếu chúng ta "và" một cái gì đó có 0 (không), kết quả sẽ luôn luôn bị sai lệch. Vì vậy, trong câu lệnh dưới đây,

0 and exp

Biểu thức exp sẽ không được đánh giá ở tất cả vì "và" với 0 sẽ luôn luôn được ước tính bằng 0 và không cần phải đánh giá biểu thức. Đây là cách trình biên dịch tự hoạt động, trong tất cả các ngôn ngữ.

Trong

1 or exp

exp của biểu thức sẽ không được đánh giá ở tất cả vì "hoặc" với 1 sẽ luôn là 1. Vì vậy, sẽ không bận tâm để đánh giá biểu thức exp vì dù sao kết quả sẽ là 1. (phương pháp tối ưu hóa trình biên dịch).

Nhưng trong trường hợp

True and exp1 or exp2

Biểu thức thứ hai exp2 sẽ không được đánh giá vì True and exp1sẽ là True khi exp1 không sai.

Tương tự như vậy trong

False and exp1 or exp2

Biểu thức exp1 sẽ không được đánh giá vì Sai tương đương với viết 0 và thực hiện "và" với 0 sẽ là 0 nhưng sau khi exp1 kể từ "hoặc" được sử dụng, nó sẽ đánh giá biểu thức exp2 sau "hoặc".


Lưu ý: - Loại phân nhánh này sử dụng "hoặc" và "và" chỉ có thể được sử dụng khi biểu thức_1 không có giá trị Truth là Sai (hoặc 0 hoặc Không hoặc danh sách trống [] hoặc chuỗi rỗng ''.) Kể từ khi biểu thức_1 trở thành Sai, sau đó biểu thức_2 sẽ được đánh giá vì sự hiện diện "hoặc" giữa exp_1 và exp_2.

Trong trường hợp bạn vẫn muốn làm cho nó hoạt động cho tất cả các trường hợp bất kể giá trị thật của exp_1 và exp_2 là gì, hãy làm điều này: -

[condition] and ([expression_1] or 1) or [expression_2] ;


Nếu bạn muốn sử dụng nó trong bối cảnh x = [condition] and ([expression_1] or 1) or [expression_2]expression_1đánh giá là sai, xsẽ 1không expression_1. Sử dụng câu trả lời được chấp nhận.
moi

18

Nhiều hơn một mẹo hơn là một câu trả lời (không cần lặp lại điều hiển nhiên trong thời gian hundreth), nhưng đôi khi tôi sử dụng nó như một lối tắt oneliner trong các cấu trúc như vậy:

if conditionX:
    print('yes')
else:
    print('nah')

, trở thành:

print('yes') if conditionX else print('nah')

Một số (nhiều :) có thể cau mày vì nó là unpythonic (thậm chí, ruby-ish :), nhưng cá nhân tôi thấy nó tự nhiên hơn - tức là cách bạn thể hiện nó bình thường, cộng với một chút trực quan hấp dẫn hơn trong các khối mã lớn.


5
Tôi thích print( 'yes' if conditionX else 'nah' )hơn câu trả lời của bạn. :-)
frederick99

Đó là nếu bạn muốn print()trong cả hai trường hợp - và có vẻ hơi pythonic hơn, tôi phải thừa nhận :) Nhưng điều gì sẽ xảy ra nếu các biểu thức / chức năng không giống nhau - giống như print('yes') if conditionX else True- để có được sự thật print()duy nhấtconditionX
Todor Minakov

Để thêm vào nhận xét của Frederick99, một lý do khác cần tránh print('yes') if conditionX else print('nah')là nó đưa ra một SyntaxError trong Python2.
Thierry Lathuille

Lý do duy nhất nó đưa ra lỗi cú pháp là vì trong bản in Python 2 là một câu lệnh - print "yes"trong khi trong Python 3 nó là một hàm - print("yes"). Điều đó có thể được giải quyết bằng cách sử dụng nó như một tuyên bố, hoặc tốt hơn - from future import print_function.
Todor Minakov

18
a if condition else b

Chỉ cần ghi nhớ kim tự tháp này nếu bạn gặp khó khăn trong việc ghi nhớ:

     condition
  if           else
a                   b 

14

Một trong những lựa chọn thay thế cho biểu thức điều kiện của Python

"yes" if boolean else "no"

như sau:

{True:"yes", False:"no"}[boolean]

có phần mở rộng tốt đẹp sau:

{True:"yes", False:"no", None:"maybe"}[boolean_or_none]

Sự thay thế ngắn nhất vẫn còn:

("no", "yes")[boolean]

nhưng không có cách nào khác

yes() if boolean else no()

nếu bạn muốn tránh việc đánh giá yes() no() , bởi vì

(no(), yes())[boolean]  # bad

cả hai no()yes()được đánh giá.


10

Nhiều ngôn ngữ lập trình bắt nguồn từ Cthường có cú pháp sau của toán tử điều kiện ternary:

<condition> ? <expression1> : <expression2>

Lúc đầu, Python B enevolent D ictator F hoặc L ife (ý tôi là Guido van Rossum, tất nhiên) đã từ chối nó (như phong cách không phải Pythonic), vì nó khá khó hiểu đối với những người không quen sử dụng Cngôn ngữ. Ngoài ra, dấu hai chấm :đã có nhiều công dụng trong Python. Sau khi PEP 308 được phê duyệt, Pythoncuối cùng đã nhận được biểu thức điều kiện tắt của chính nó (những gì chúng ta sử dụng bây giờ):

<expression1> if <condition> else <expression2>

Vì vậy, trước tiên nó đánh giá điều kiện. Nếu nó trả về True, biểu thức1 sẽ được ước tính để đưa ra kết quả, nếu không thì biểu thức 2 sẽ được ước tính. Do cơ chế đánh giá lười biếng - chỉ một biểu thức sẽ được thực thi.

Dưới đây là một số ví dụ (điều kiện sẽ được đánh giá từ trái sang phải):

pressure = 10
print('High' if pressure < 20 else 'Critical')

# Result is 'High'

Toán tử ternary có thể được nối tiếp trong chuỗi:

pressure = 5
print('Normal' if pressure < 10 else 'High' if pressure < 20 else 'Critical')

# Result is 'Normal'

Cái sau giống như cái trước:

pressure = 5

if pressure < 20:
    if pressure < 10:
        print('Normal')
    else:
        print('High')
else:
    print('Critical')

# Result is 'Normal'

Hi vọng điêu nay co ich.


10

Như đã trả lời, vâng, có một toán tử ternary trong python:

<expression 1> if <condition> else <expression 2>

Thông tin thêm:

Nếu <expression 1>là điều kiện bạn có thể sử dụng đánh giá ngắn cirquito :

a = True
b = False

# Instead of this:
x = a if a else b

# You could use Short-cirquit evaluation:
x = a or b

PS: Tất nhiên, việc đánh giá xơ gan ngắn không phải là toán tử ternary nhưng thường thì ternary được sử dụng trong trường hợp ngắn mạch là đủ.


1
Upvote cho short-circuitđánh giá đó .
CodeIt

7

CÓ, python có một toán tử ternary, đây là cú pháp và mã ví dụ để chứng minh tương tự :)

#[On true] if [expression] else[On false]
# if the expression evaluates to true then it will pass On true otherwise On false


a= input("Enter the First Number ")
b= input("Enter the Second Number ")

print("A is Bigger") if a>b else print("B is Bigger")

Tôi đã thêm một ví dụ câu lệnh một dòng để kiểm tra số nào là lớn để xây dựng thêm
PythonLover

1
printthực sự không phải là một lựa chọn tốt, vì điều này sẽ cung cấp một SyntaxError trong Python2.
Thierry Lathuille

@Thierry Lathuille ở đây Tôi đã sử dụng hàm print () không in câu lệnh, hàm in là dành cho Python 3 trong khi câu lệnh in dành cho Python 2
PythonLover

Câu hỏi đã được hỏi trên SO, chỉ cần thử với Python 2 và bạn sẽ tự mình nhìn thấy. 'print (' hello ') là một cú pháp hoàn toàn hợp lệ trong Python 2.7, nhưng cách nó được phân tích cú pháp làm cho mã của bạn ở trên ném một SyntaxError.
Thierry Lathuille

2

Python có một hình thức ternary cho các bài tập; tuy nhiên có thể có một dạng ngắn hơn mà mọi người nên biết.

Rất cần phải gán cho một giá trị biến hoặc giá trị khác tùy thuộc vào một điều kiện.

>>> li1 = None
>>> li2 = [1, 2, 3]
>>> 
>>> if li1:
...     a = li1
... else:
...     a = li2
...     
>>> a
[1, 2, 3]

^ Đây là hình thức dài để làm bài tập như vậy.

Dưới đây là hình thức chim nhạn. Nhưng đây không phải là cách ngắn gọn nhất - xem ví dụ cuối cùng.

>>> a = li1 if li1 else li2
>>> 
>>> a
[1, 2, 3]
>>> 

Với Python, bạn chỉ cần sử dụng orcho các bài tập thay thế.

>>> a = li1 or li2
>>> 
>>> a
[1, 2, 3]
>>> 

Các công việc trên kể từ li1Nonevà interp coi đó là Sai trong các biểu thức logic. Sau đó, interp di chuyển và đánh giá biểu thức thứ hai, đây không Nonephải là một danh sách trống - vì vậy nó được gán cho a.

Điều này cũng hoạt động với danh sách trống. Ví dụ, nếu bạn muốn chỉ định adanh sách nào có mục.

>>> li1 = []
>>> li2 = [1, 2, 3]
>>> 
>>> a = li1 or li2
>>> 
>>> a
[1, 2, 3]
>>> 

Biết điều này, bạn có thể chỉ cần các bài tập như vậy bất cứ khi nào bạn gặp chúng. Điều này cũng hoạt động với chuỗi và lặp khác. Bạn có thể gán abất kỳ chuỗi nào không trống.

>>> s1 = ''
>>> s2 = 'hello world'
>>> 
>>> a = s1 or s2
>>> 
>>> a
'hello world'
>>> 

Tôi luôn thích cú pháp ternary C, nhưng Python đưa nó tiến thêm một bước!

Tôi hiểu rằng một số người có thể nói rằng đây không phải là một lựa chọn phong cách tốt bởi vì nó phụ thuộc vào cơ học không rõ ràng ngay lập tức đối với tất cả các nhà phát triển. Cá nhân tôi không đồng ý với quan điểm đó. Python là một ngôn ngữ giàu cú pháp với nhiều thủ thuật thành ngữ không rõ ràng ngay lập tức đối với trình duyệt. Nhưng bạn càng tìm hiểu và hiểu các cơ chế của hệ thống cơ bản, bạn càng đánh giá cao nó.


1

Các câu trả lời khác nói chính xác về toán tử ternary Python. Tôi muốn bổ sung bằng cách đề cập đến một kịch bản mà toán tử ternary thường được sử dụng nhưng trong đó có một thành ngữ tốt hơn. Đây là kịch bản sử dụng một giá trị mặc định.

Giả sử chúng ta muốn sử dụng option_valuevới một giá trị mặc định nếu nó không được đặt:

run_algorithm(option_value if option_value is not None else 10)

hoặc đơn giản

run_algorithm(option_value if option_value else 10)

Tuy nhiên, một giải pháp tốt hơn bao giờ hết chỉ đơn giản là viết

run_algorithm(option_value or 10)

-2

nếu biến được định nghĩa và bạn muốn kiểm tra xem nó có giá trị không a or b

def test(myvar=None):
    # shorter than: print myvar if myvar else "no Input"
    print myvar or "no Input"

test()
test([])
test(False)
test('hello')
test(['Hello'])
test(True)

sẽ xuất

no Input
no Input
no Input
hello
['Hello']
True

1
Mặc dù hữu ích cho các vấn đề tương tự, đây không phải là một điều kiện ternary. Nó hoạt động để thay thế x if x else y, nhưng không x if z else y.
Perkins

-2

Một cách gọn gàng để xâu chuỗi nhiều toán tử:

f = lambda x,y: 'greater' if x > y else 'less' if y > x else 'equal'

array = [(0,0),(0,1),(1,0),(1,1)]

for a in array:
  x, y = a[0], a[1]
  print(f(x,y))

# Output is:
#   equal,
#   less,
#   greater,
#   equal

-2

Tôi thấy rườm rà cú pháp python mặc định val = a if cond else b, vì vậy đôi khi tôi làm điều này:

iif = lambda (cond, a, b): a if cond else b
# so I can then use it like:
val = iif(cond, a, b)

Tất nhiên, nó có nhược điểm là luôn luôn đánh giá cả hai mặt (a và b), nhưng cú pháp rõ ràng hơn với tôi


Đây dường như là gấp đôi số lượng công việc, sử dụng nhiều RAM hơn và bị xáo trộn nhiều hơn so với val = a if cond else btuyên bố đơn giản hơn .
eatsfood

-3
is_spacial=True if gender = "Female" else (True if age >= 65 else False)

**

nó có thể được lồng theo nhu cầu của bạn. may mắn nhất

**

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.