• Python »
  • 3.11.5 Documentation »
  • The Python Language Reference »
  • 6. Expressions
  • Theme Auto Light Dark |

6. Expressions ¶

This chapter explains the meaning of the elements of expressions in Python.

Syntax Notes: In this and the following chapters, extended BNF notation will be used to describe syntax, not lexical analysis. When (one alternative of) a syntax rule has the form

and no semantics are given, the semantics of this form of name are the same as for othername .

6.1. Arithmetic conversions ¶

When a description of an arithmetic operator below uses the phrase “the numeric arguments are converted to a common type”, this means that the operator implementation for built-in types works as follows:

If either argument is a complex number, the other is converted to complex;

otherwise, if either argument is a floating point number, the other is converted to floating point;

otherwise, both must be integers and no conversion is necessary.

Some additional rules apply for certain operators (e.g., a string as a left argument to the ‘%’ operator). Extensions must define their own conversion behavior.

6.2. Atoms ¶

Atoms are the most basic elements of expressions. The simplest atoms are identifiers or literals. Forms enclosed in parentheses, brackets or braces are also categorized syntactically as atoms. The syntax for atoms is:

6.2.1. Identifiers (Names) ¶

An identifier occurring as an atom is a name. See section Identifiers and keywords for lexical definition and section Naming and binding for documentation of naming and binding.

When the name is bound to an object, evaluation of the atom yields that object. When a name is not bound, an attempt to evaluate it raises a NameError exception.

Private name mangling: When an identifier that textually occurs in a class definition begins with two or more underscore characters and does not end in two or more underscores, it is considered a private name of that class. Private names are transformed to a longer form before code is generated for them. The transformation inserts the class name, with leading underscores removed and a single underscore inserted, in front of the name. For example, the identifier __spam occurring in a class named Ham will be transformed to _Ham__spam . This transformation is independent of the syntactical context in which the identifier is used. If the transformed name is extremely long (longer than 255 characters), implementation defined truncation may happen. If the class name consists only of underscores, no transformation is done.

6.2.2. Literals ¶

Python supports string and bytes literals and various numeric literals:

Evaluation of a literal yields an object of the given type (string, bytes, integer, floating point number, complex number) with the given value. The value may be approximated in the case of floating point and imaginary (complex) literals. See section Literals for details.

All literals correspond to immutable data types, and hence the object’s identity is less important than its value. Multiple evaluations of literals with the same value (either the same occurrence in the program text or a different occurrence) may obtain the same object or a different object with the same value.

6.2.3. Parenthesized forms ¶

A parenthesized form is an optional expression list enclosed in parentheses:

A parenthesized expression list yields whatever that expression list yields: if the list contains at least one comma, it yields a tuple; otherwise, it yields the single expression that makes up the expression list.

An empty pair of parentheses yields an empty tuple object. Since tuples are immutable, the same rules as for literals apply (i.e., two occurrences of the empty tuple may or may not yield the same object).

Note that tuples are not formed by the parentheses, but rather by use of the comma. The exception is the empty tuple, for which parentheses are required — allowing unparenthesized “nothing” in expressions would cause ambiguities and allow common typos to pass uncaught.

6.2.4. Displays for lists, sets and dictionaries ¶

For constructing a list, a set or a dictionary Python provides special syntax called “displays”, each of them in two flavors:

either the container contents are listed explicitly, or

they are computed via a set of looping and filtering instructions, called a comprehension .

Common syntax elements for comprehensions are:

The comprehension consists of a single expression followed by at least one for clause and zero or more for or if clauses. In this case, the elements of the new container are those that would be produced by considering each of the for or if clauses a block, nesting from left to right, and evaluating the expression to produce an element each time the innermost block is reached.

However, aside from the iterable expression in the leftmost for clause, the comprehension is executed in a separate implicitly nested scope. This ensures that names assigned to in the target list don’t “leak” into the enclosing scope.

The iterable expression in the leftmost for clause is evaluated directly in the enclosing scope and then passed as an argument to the implicitly nested scope. Subsequent for clauses and any filter condition in the leftmost for clause cannot be evaluated in the enclosing scope as they may depend on the values obtained from the leftmost iterable. For example: [x*y for x in range(10) for y in range(x, x+10)] .

To ensure the comprehension always results in a container of the appropriate type, yield and yield from expressions are prohibited in the implicitly nested scope.

Since Python 3.6, in an async def function, an async for clause may be used to iterate over a asynchronous iterator . A comprehension in an async def function may consist of either a for or async for clause following the leading expression, may contain additional for or async for clauses, and may also use await expressions. If a comprehension contains either async for clauses or await expressions or other asynchronous comprehensions it is called an asynchronous comprehension . An asynchronous comprehension may suspend the execution of the coroutine function in which it appears. See also PEP 530 .

New in version 3.6: Asynchronous comprehensions were introduced.

Changed in version 3.8: yield and yield from prohibited in the implicitly nested scope.

Changed in version 3.11: Asynchronous comprehensions are now allowed inside comprehensions in asynchronous functions. Outer comprehensions implicitly become asynchronous.

6.2.5. List displays ¶

A list display is a possibly empty series of expressions enclosed in square brackets:

A list display yields a new list object, the contents being specified by either a list of expressions or a comprehension. When a comma-separated list of expressions is supplied, its elements are evaluated from left to right and placed into the list object in that order. When a comprehension is supplied, the list is constructed from the elements resulting from the comprehension.

6.2.6. Set displays ¶

A set display is denoted by curly braces and distinguishable from dictionary displays by the lack of colons separating keys and values:

A set display yields a new mutable set object, the contents being specified by either a sequence of expressions or a comprehension. When a comma-separated list of expressions is supplied, its elements are evaluated from left to right and added to the set object. When a comprehension is supplied, the set is constructed from the elements resulting from the comprehension.

An empty set cannot be constructed with {} ; this literal constructs an empty dictionary.

6.2.7. Dictionary displays ¶

A dictionary display is a possibly empty series of dict items (key/value pairs) enclosed in curly braces:

A dictionary display yields a new dictionary object.

If a comma-separated sequence of dict items is given, they are evaluated from left to right to define the entries of the dictionary: each key object is used as a key into the dictionary to store the corresponding value. This means that you can specify the same key multiple times in the dict item list, and the final dictionary’s value for that key will be the last one given.

A double asterisk ** denotes dictionary unpacking . Its operand must be a mapping . Each mapping item is added to the new dictionary. Later values replace values already set by earlier dict items and earlier dictionary unpackings.

New in version 3.5: Unpacking into dictionary displays, originally proposed by PEP 448 .

A dict comprehension, in contrast to list and set comprehensions, needs two expressions separated with a colon followed by the usual “for” and “if” clauses. When the comprehension is run, the resulting key and value elements are inserted in the new dictionary in the order they are produced.

Restrictions on the types of the key values are listed earlier in section The standard type hierarchy . (To summarize, the key type should be hashable , which excludes all mutable objects.) Clashes between duplicate keys are not detected; the last value (textually rightmost in the display) stored for a given key value prevails.

Changed in version 3.8: Prior to Python 3.8, in dict comprehensions, the evaluation order of key and value was not well-defined. In CPython, the value was evaluated before the key. Starting with 3.8, the key is evaluated before the value, as proposed by PEP 572 .

6.2.8. Generator expressions ¶

A generator expression is a compact generator notation in parentheses:

A generator expression yields a new generator object. Its syntax is the same as for comprehensions, except that it is enclosed in parentheses instead of brackets or curly braces.

Variables used in the generator expression are evaluated lazily when the __next__() method is called for the generator object (in the same fashion as normal generators). However, the iterable expression in the leftmost for clause is immediately evaluated, so that an error produced by it will be emitted at the point where the generator expression is defined, rather than at the point where the first value is retrieved. Subsequent for clauses and any filter condition in the leftmost for clause cannot be evaluated in the enclosing scope as they may depend on the values obtained from the leftmost iterable. For example: (x*y for x in range(10) for y in range(x, x+10)) .

The parentheses can be omitted on calls with only one argument. See section Calls for details.

To avoid interfering with the expected operation of the generator expression itself, yield and yield from expressions are prohibited in the implicitly defined generator.

If a generator expression contains either async for clauses or await expressions it is called an asynchronous generator expression . An asynchronous generator expression returns a new asynchronous generator object, which is an asynchronous iterator (see Asynchronous Iterators ).

New in version 3.6: Asynchronous generator expressions were introduced.

Changed in version 3.7: Prior to Python 3.7, asynchronous generator expressions could only appear in async def coroutines. Starting with 3.7, any function can use asynchronous generator expressions.

6.2.9. Yield expressions ¶

The yield expression is used when defining a generator function or an asynchronous generator function and thus can only be used in the body of a function definition. Using a yield expression in a function’s body causes that function to be a generator function, and using it in an async def function’s body causes that coroutine function to be an asynchronous generator function. For example:

Due to their side effects on the containing scope, yield expressions are not permitted as part of the implicitly defined scopes used to implement comprehensions and generator expressions.

Changed in version 3.8: Yield expressions prohibited in the implicitly nested scopes used to implement comprehensions and generator expressions.

Generator functions are described below, while asynchronous generator functions are described separately in section Asynchronous generator functions .

When a generator function is called, it returns an iterator known as a generator. That generator then controls the execution of the generator function. The execution starts when one of the generator’s methods is called. At that time, the execution proceeds to the first yield expression, where it is suspended again, returning the value of expression_list to the generator’s caller, or None if expression_list is omitted. By suspended, we mean that all local state is retained, including the current bindings of local variables, the instruction pointer, the internal evaluation stack, and the state of any exception handling. When the execution is resumed by calling one of the generator’s methods, the function can proceed exactly as if the yield expression were just another external call. The value of the yield expression after resuming depends on the method which resumed the execution. If __next__() is used (typically via either a for or the next() builtin) then the result is None . Otherwise, if send() is used, then the result will be the value passed in to that method.

All of this makes generator functions quite similar to coroutines; they yield multiple times, they have more than one entry point and their execution can be suspended. The only difference is that a generator function cannot control where the execution should continue after it yields; the control is always transferred to the generator’s caller.

Yield expressions are allowed anywhere in a try construct. If the generator is not resumed before it is finalized (by reaching a zero reference count or by being garbage collected), the generator-iterator’s close() method will be called, allowing any pending finally clauses to execute.

When yield from <expr> is used, the supplied expression must be an iterable. The values produced by iterating that iterable are passed directly to the caller of the current generator’s methods. Any values passed in with send() and any exceptions passed in with throw() are passed to the underlying iterator if it has the appropriate methods. If this is not the case, then send() will raise AttributeError or TypeError , while throw() will just raise the passed in exception immediately.

When the underlying iterator is complete, the value attribute of the raised StopIteration instance becomes the value of the yield expression. It can be either set explicitly when raising StopIteration , or automatically when the subiterator is a generator (by returning a value from the subgenerator).

Changed in version 3.3: Added yield from <expr> to delegate control flow to a subiterator.

The parentheses may be omitted when the yield expression is the sole expression on the right hand side of an assignment statement.

The proposal for adding generators and the yield statement to Python.

The proposal to enhance the API and syntax of generators, making them usable as simple coroutines.

The proposal to introduce the yield_from syntax, making delegation to subgenerators easy.

The proposal that expanded on PEP 492 by adding generator capabilities to coroutine functions.

6.2.9.1. Generator-iterator methods ¶

This subsection describes the methods of a generator iterator. They can be used to control the execution of a generator function.

Note that calling any of the generator methods below when the generator is already executing raises a ValueError exception.

Starts the execution of a generator function or resumes it at the last executed yield expression. When a generator function is resumed with a __next__() method, the current yield expression always evaluates to None . The execution then continues to the next yield expression, where the generator is suspended again, and the value of the expression_list is returned to __next__() ’s caller. If the generator exits without yielding another value, a StopIteration exception is raised.

This method is normally called implicitly, e.g. by a for loop, or by the built-in next() function.

Resumes the execution and “sends” a value into the generator function. The value argument becomes the result of the current yield expression. The send() method returns the next value yielded by the generator, or raises StopIteration if the generator exits without yielding another value. When send() is called to start the generator, it must be called with None as the argument, because there is no yield expression that could receive the value.

Raises an exception at the point where the generator was paused, and returns the next value yielded by the generator function. If the generator exits without yielding another value, a StopIteration exception is raised. If the generator function does not catch the passed-in exception, or raises a different exception, then that exception propagates to the caller.

In typical use, this is called with a single exception instance similar to the way the raise keyword is used.

For backwards compatibility, however, the second signature is supported, following a convention from older versions of Python. The type argument should be an exception class, and value should be an exception instance. If the value is not provided, the type constructor is called to get an instance. If traceback is provided, it is set on the exception, otherwise any existing __traceback__ attribute stored in value may be cleared.

Raises a GeneratorExit at the point where the generator function was paused. If the generator function then exits gracefully, is already closed, or raises GeneratorExit (by not catching the exception), close returns to its caller. If the generator yields a value, a RuntimeError is raised. If the generator raises any other exception, it is propagated to the caller. close() does nothing if the generator has already exited due to an exception or normal exit.

6.2.9.2. Examples ¶

Here is a simple example that demonstrates the behavior of generators and generator functions:

For examples using yield from , see PEP 380: Syntax for Delegating to a Subgenerator in “What’s New in Python.”

6.2.9.3. Asynchronous generator functions ¶

The presence of a yield expression in a function or method defined using async def further defines the function as an asynchronous generator function.

When an asynchronous generator function is called, it returns an asynchronous iterator known as an asynchronous generator object. That object then controls the execution of the generator function. An asynchronous generator object is typically used in an async for statement in a coroutine function analogously to how a generator object would be used in a for statement.

Calling one of the asynchronous generator’s methods returns an awaitable object, and the execution starts when this object is awaited on. At that time, the execution proceeds to the first yield expression, where it is suspended again, returning the value of expression_list to the awaiting coroutine. As with a generator, suspension means that all local state is retained, including the current bindings of local variables, the instruction pointer, the internal evaluation stack, and the state of any exception handling. When the execution is resumed by awaiting on the next object returned by the asynchronous generator’s methods, the function can proceed exactly as if the yield expression were just another external call. The value of the yield expression after resuming depends on the method which resumed the execution. If __anext__() is used then the result is None . Otherwise, if asend() is used, then the result will be the value passed in to that method.

If an asynchronous generator happens to exit early by break , the caller task being cancelled, or other exceptions, the generator’s async cleanup code will run and possibly raise exceptions or access context variables in an unexpected context–perhaps after the lifetime of tasks it depends, or during the event loop shutdown when the async-generator garbage collection hook is called. To prevent this, the caller must explicitly close the async generator by calling aclose() method to finalize the generator and ultimately detach it from the event loop.

In an asynchronous generator function, yield expressions are allowed anywhere in a try construct. However, if an asynchronous generator is not resumed before it is finalized (by reaching a zero reference count or by being garbage collected), then a yield expression within a try construct could result in a failure to execute pending finally clauses. In this case, it is the responsibility of the event loop or scheduler running the asynchronous generator to call the asynchronous generator-iterator’s aclose() method and run the resulting coroutine object, thus allowing any pending finally clauses to execute.

To take care of finalization upon event loop termination, an event loop should define a finalizer function which takes an asynchronous generator-iterator and presumably calls aclose() and executes the coroutine. This finalizer may be registered by calling sys.set_asyncgen_hooks() . When first iterated over, an asynchronous generator-iterator will store the registered finalizer to be called upon finalization. For a reference example of a finalizer method see the implementation of asyncio.Loop.shutdown_asyncgens in Lib/asyncio/base_events.py .

The expression yield from <expr> is a syntax error when used in an asynchronous generator function.

6.2.9.4. Asynchronous generator-iterator methods ¶

This subsection describes the methods of an asynchronous generator iterator, which are used to control the execution of a generator function.

Returns an awaitable which when run starts to execute the asynchronous generator or resumes it at the last executed yield expression. When an asynchronous generator function is resumed with an __anext__() method, the current yield expression always evaluates to None in the returned awaitable, which when run will continue to the next yield expression. The value of the expression_list of the yield expression is the value of the StopIteration exception raised by the completing coroutine. If the asynchronous generator exits without yielding another value, the awaitable instead raises a StopAsyncIteration exception, signalling that the asynchronous iteration has completed.

This method is normally called implicitly by a async for loop.

Returns an awaitable which when run resumes the execution of the asynchronous generator. As with the send() method for a generator, this “sends” a value into the asynchronous generator function, and the value argument becomes the result of the current yield expression. The awaitable returned by the asend() method will return the next value yielded by the generator as the value of the raised StopIteration , or raises StopAsyncIteration if the asynchronous generator exits without yielding another value. When asend() is called to start the asynchronous generator, it must be called with None as the argument, because there is no yield expression that could receive the value.

Returns an awaitable that raises an exception of type type at the point where the asynchronous generator was paused, and returns the next value yielded by the generator function as the value of the raised StopIteration exception. If the asynchronous generator exits without yielding another value, a StopAsyncIteration exception is raised by the awaitable. If the generator function does not catch the passed-in exception, or raises a different exception, then when the awaitable is run that exception propagates to the caller of the awaitable.

Returns an awaitable that when run will throw a GeneratorExit into the asynchronous generator function at the point where it was paused. If the asynchronous generator function then exits gracefully, is already closed, or raises GeneratorExit (by not catching the exception), then the returned awaitable will raise a StopIteration exception. Any further awaitables returned by subsequent calls to the asynchronous generator will raise a StopAsyncIteration exception. If the asynchronous generator yields a value, a RuntimeError is raised by the awaitable. If the asynchronous generator raises any other exception, it is propagated to the caller of the awaitable. If the asynchronous generator has already exited due to an exception or normal exit, then further calls to aclose() will return an awaitable that does nothing.

6.3. Primaries ¶

Primaries represent the most tightly bound operations of the language. Their syntax is:

6.3.1. Attribute references ¶

An attribute reference is a primary followed by a period and a name:

The primary must evaluate to an object of a type that supports attribute references, which most objects do. This object is then asked to produce the attribute whose name is the identifier. This production can be customized by overriding the __getattr__() method. If this attribute is not available, the exception AttributeError is raised. Otherwise, the type and value of the object produced is determined by the object. Multiple evaluations of the same attribute reference may yield different objects.

6.3.2. Subscriptions ¶

The subscription of an instance of a container class will generally select an element from the container. The subscription of a generic class will generally return a GenericAlias object.

When an object is subscripted, the interpreter will evaluate the primary and the expression list.

The primary must evaluate to an object that supports subscription. An object may support subscription through defining one or both of __getitem__() and __class_getitem__() . When the primary is subscripted, the evaluated result of the expression list will be passed to one of these methods. For more details on when __class_getitem__ is called instead of __getitem__ , see __class_getitem__ versus __getitem__ .

If the expression list contains at least one comma, it will evaluate to a tuple containing the items of the expression list. Otherwise, the expression list will evaluate to the value of the list’s sole member.

For built-in objects, there are two types of objects that support subscription via __getitem__() :

Mappings. If the primary is a mapping , the expression list must evaluate to an object whose value is one of the keys of the mapping, and the subscription selects the value in the mapping that corresponds to that key. An example of a builtin mapping class is the dict class.

Sequences. If the primary is a sequence , the expression list must evaluate to an int or a slice (as discussed in the following section). Examples of builtin sequence classes include the str , list and tuple classes.

The formal syntax makes no special provision for negative indices in sequences . However, built-in sequences all provide a __getitem__() method that interprets negative indices by adding the length of the sequence to the index so that, for example, x[-1] selects the last item of x . The resulting value must be a nonnegative integer less than the number of items in the sequence, and the subscription selects the item whose index is that value (counting from zero). Since the support for negative indices and slicing occurs in the object’s __getitem__() method, subclasses overriding this method will need to explicitly add that support.

A string is a special kind of sequence whose items are characters . A character is not a separate data type but a string of exactly one character.

6.3.3. Slicings ¶

A slicing selects a range of items in a sequence object (e.g., a string, tuple or list). Slicings may be used as expressions or as targets in assignment or del statements. The syntax for a slicing:

There is ambiguity in the formal syntax here: anything that looks like an expression list also looks like a slice list, so any subscription can be interpreted as a slicing. Rather than further complicating the syntax, this is disambiguated by defining that in this case the interpretation as a subscription takes priority over the interpretation as a slicing (this is the case if the slice list contains no proper slice).

The semantics for a slicing are as follows. The primary is indexed (using the same __getitem__() method as normal subscription) with a key that is constructed from the slice list, as follows. If the slice list contains at least one comma, the key is a tuple containing the conversion of the slice items; otherwise, the conversion of the lone slice item is the key. The conversion of a slice item that is an expression is that expression. The conversion of a proper slice is a slice object (see section The standard type hierarchy ) whose start , stop and step attributes are the values of the expressions given as lower bound, upper bound and stride, respectively, substituting None for missing expressions.

6.3.4. Calls ¶

A call calls a callable object (e.g., a function ) with a possibly empty series of arguments :

An optional trailing comma may be present after the positional and keyword arguments but does not affect the semantics.

The primary must evaluate to a callable object (user-defined functions, built-in functions, methods of built-in objects, class objects, methods of class instances, and all objects having a __call__() method are callable). All argument expressions are evaluated before the call is attempted. Please refer to section Function definitions for the syntax of formal parameter lists.

If keyword arguments are present, they are first converted to positional arguments, as follows. First, a list of unfilled slots is created for the formal parameters. If there are N positional arguments, they are placed in the first N slots. Next, for each keyword argument, the identifier is used to determine the corresponding slot (if the identifier is the same as the first formal parameter name, the first slot is used, and so on). If the slot is already filled, a TypeError exception is raised. Otherwise, the argument is placed in the slot, filling it (even if the expression is None , it fills the slot). When all arguments have been processed, the slots that are still unfilled are filled with the corresponding default value from the function definition. (Default values are calculated, once, when the function is defined; thus, a mutable object such as a list or dictionary used as default value will be shared by all calls that don’t specify an argument value for the corresponding slot; this should usually be avoided.) If there are any unfilled slots for which no default value is specified, a TypeError exception is raised. Otherwise, the list of filled slots is used as the argument list for the call.

CPython implementation detail: An implementation may provide built-in functions whose positional parameters do not have names, even if they are ‘named’ for the purpose of documentation, and which therefore cannot be supplied by keyword. In CPython, this is the case for functions implemented in C that use PyArg_ParseTuple() to parse their arguments.

If there are more positional arguments than there are formal parameter slots, a TypeError exception is raised, unless a formal parameter using the syntax *identifier is present; in this case, that formal parameter receives a tuple containing the excess positional arguments (or an empty tuple if there were no excess positional arguments).

If any keyword argument does not correspond to a formal parameter name, a TypeError exception is raised, unless a formal parameter using the syntax **identifier is present; in this case, that formal parameter receives a dictionary containing the excess keyword arguments (using the keywords as keys and the argument values as corresponding values), or a (new) empty dictionary if there were no excess keyword arguments.

If the syntax *expression appears in the function call, expression must evaluate to an iterable . Elements from these iterables are treated as if they were additional positional arguments. For the call f(x1, x2, *y, x3, x4) , if y evaluates to a sequence y1 , …, yM , this is equivalent to a call with M+4 positional arguments x1 , x2 , y1 , …, yM , x3 , x4 .

A consequence of this is that although the *expression syntax may appear after explicit keyword arguments, it is processed before the keyword arguments (and any **expression arguments – see below). So:

It is unusual for both keyword arguments and the *expression syntax to be used in the same call, so in practice this confusion does not often arise.

If the syntax **expression appears in the function call, expression must evaluate to a mapping , the contents of which are treated as additional keyword arguments. If a parameter matching a key has already been given a value (by an explicit keyword argument, or from another unpacking), a TypeError exception is raised.

When **expression is used, each key in this mapping must be a string. Each value from the mapping is assigned to the first formal parameter eligible for keyword assignment whose name is equal to the key. A key need not be a Python identifier (e.g. "max-temp °F" is acceptable, although it will not match any formal parameter that could be declared). If there is no match to a formal parameter the key-value pair is collected by the ** parameter, if there is one, or if there is not, a TypeError exception is raised.

Formal parameters using the syntax *identifier or **identifier cannot be used as positional argument slots or as keyword argument names.

Changed in version 3.5: Function calls accept any number of * and ** unpackings, positional arguments may follow iterable unpackings ( * ), and keyword arguments may follow dictionary unpackings ( ** ). Originally proposed by PEP 448 .

A call always returns some value, possibly None , unless it raises an exception. How this value is computed depends on the type of the callable object.

The code block for the function is executed, passing it the argument list. The first thing the code block will do is bind the formal parameters to the arguments; this is described in section Function definitions . When the code block executes a return statement, this specifies the return value of the function call.

The result is up to the interpreter; see Built-in Functions for the descriptions of built-in functions and methods.

A new instance of that class is returned.

The corresponding user-defined function is called, with an argument list that is one longer than the argument list of the call: the instance becomes the first argument.

The class must define a __call__() method; the effect is then the same as if that method was called.

6.4. Await expression ¶

Suspend the execution of coroutine on an awaitable object. Can only be used inside a coroutine function .

New in version 3.5.

6.5. The power operator ¶

The power operator binds more tightly than unary operators on its left; it binds less tightly than unary operators on its right. The syntax is:

Thus, in an unparenthesized sequence of power and unary operators, the operators are evaluated from right to left (this does not constrain the evaluation order for the operands): -1**2 results in -1 .

The power operator has the same semantics as the built-in pow() function, when called with two arguments: it yields its left argument raised to the power of its right argument. The numeric arguments are first converted to a common type, and the result is of that type.

For int operands, the result has the same type as the operands unless the second argument is negative; in that case, all arguments are converted to float and a float result is delivered. For example, 10**2 returns 100 , but 10**-2 returns 0.01 .

Raising 0.0 to a negative power results in a ZeroDivisionError . Raising a negative number to a fractional power results in a complex number. (In earlier versions it raised a ValueError .)

This operation can be customized using the special __pow__() method.

6.6. Unary arithmetic and bitwise operations ¶

All unary arithmetic and bitwise operations have the same priority:

The unary - (minus) operator yields the negation of its numeric argument; the operation can be overridden with the __neg__() special method.

The unary + (plus) operator yields its numeric argument unchanged; the operation can be overridden with the __pos__() special method.

The unary ~ (invert) operator yields the bitwise inversion of its integer argument. The bitwise inversion of x is defined as -(x+1) . It only applies to integral numbers or to custom objects that override the __invert__() special method.

In all three cases, if the argument does not have the proper type, a TypeError exception is raised.

6.7. Binary arithmetic operations ¶

The binary arithmetic operations have the conventional priority levels. Note that some of these operations also apply to certain non-numeric types. Apart from the power operator, there are only two levels, one for multiplicative operators and one for additive operators:

The * (multiplication) operator yields the product of its arguments. The arguments must either both be numbers, or one argument must be an integer and the other must be a sequence. In the former case, the numbers are converted to a common type and then multiplied together. In the latter case, sequence repetition is performed; a negative repetition factor yields an empty sequence.

This operation can be customized using the special __mul__() and __rmul__() methods.

The @ (at) operator is intended to be used for matrix multiplication. No builtin Python types implement this operator.

The / (division) and // (floor division) operators yield the quotient of their arguments. The numeric arguments are first converted to a common type. Division of integers yields a float, while floor division of integers results in an integer; the result is that of mathematical division with the ‘floor’ function applied to the result. Division by zero raises the ZeroDivisionError exception.

This operation can be customized using the special __truediv__() and __floordiv__() methods.

The % (modulo) operator yields the remainder from the division of the first argument by the second. The numeric arguments are first converted to a common type. A zero right argument raises the ZeroDivisionError exception. The arguments may be floating point numbers, e.g., 3.14%0.7 equals 0.34 (since 3.14 equals 4*0.7 + 0.34 .) The modulo operator always yields a result with the same sign as its second operand (or zero); the absolute value of the result is strictly smaller than the absolute value of the second operand 1 .

The floor division and modulo operators are connected by the following identity: x == (x//y)*y + (x%y) . Floor division and modulo are also connected with the built-in function divmod() : divmod(x, y) == (x//y, x%y) . 2 .

In addition to performing the modulo operation on numbers, the % operator is also overloaded by string objects to perform old-style string formatting (also known as interpolation). The syntax for string formatting is described in the Python Library Reference, section printf-style String Formatting .

The modulo operation can be customized using the special __mod__() method.

The floor division operator, the modulo operator, and the divmod() function are not defined for complex numbers. Instead, convert to a floating point number using the abs() function if appropriate.

The + (addition) operator yields the sum of its arguments. The arguments must either both be numbers or both be sequences of the same type. In the former case, the numbers are converted to a common type and then added together. In the latter case, the sequences are concatenated.

This operation can be customized using the special __add__() and __radd__() methods.

The - (subtraction) operator yields the difference of its arguments. The numeric arguments are first converted to a common type.

This operation can be customized using the special __sub__() method.

6.8. Shifting operations ¶

The shifting operations have lower priority than the arithmetic operations:

These operators accept integers as arguments. They shift the first argument to the left or right by the number of bits given by the second argument.

This operation can be customized using the special __lshift__() and __rshift__() methods.

A right shift by n bits is defined as floor division by pow(2,n) . A left shift by n bits is defined as multiplication with pow(2,n) .

6.9. Binary bitwise operations ¶

Each of the three bitwise operations has a different priority level:

The & operator yields the bitwise AND of its arguments, which must be integers or one of them must be a custom object overriding __and__() or __rand__() special methods.

The ^ operator yields the bitwise XOR (exclusive OR) of its arguments, which must be integers or one of them must be a custom object overriding __xor__() or __rxor__() special methods.

The | operator yields the bitwise (inclusive) OR of its arguments, which must be integers or one of them must be a custom object overriding __or__() or __ror__() special methods.

6.10. Comparisons ¶

Unlike C, all comparison operations in Python have the same priority, which is lower than that of any arithmetic, shifting or bitwise operation. Also unlike C, expressions like a < b < c have the interpretation that is conventional in mathematics:

Comparisons yield boolean values: True or False . Custom rich comparison methods may return non-boolean values. In this case Python will call bool() on such value in boolean contexts.

Comparisons can be chained arbitrarily, e.g., x < y <= z is equivalent to x < y and y <= z , except that y is evaluated only once (but in both cases z is not evaluated at all when x < y is found to be false).

Formally, if a , b , c , …, y , z are expressions and op1 , op2 , …, opN are comparison operators, then a op1 b op2 c ... y opN z is equivalent to a op1 b and b op2 c and ... y opN z , except that each expression is evaluated at most once.

Note that a op1 b op2 c doesn’t imply any kind of comparison between a and c , so that, e.g., x < y > z is perfectly legal (though perhaps not pretty).

6.10.1. Value comparisons ¶

The operators < , > , == , >= , <= , and != compare the values of two objects. The objects do not need to have the same type.

Chapter Objects, values and types states that objects have a value (in addition to type and identity). The value of an object is a rather abstract notion in Python: For example, there is no canonical access method for an object’s value. Also, there is no requirement that the value of an object should be constructed in a particular way, e.g. comprised of all its data attributes. Comparison operators implement a particular notion of what the value of an object is. One can think of them as defining the value of an object indirectly, by means of their comparison implementation.

Because all types are (direct or indirect) subtypes of object , they inherit the default comparison behavior from object . Types can customize their comparison behavior by implementing rich comparison methods like __lt__() , described in Basic customization .

The default behavior for equality comparison ( == and != ) is based on the identity of the objects. Hence, equality comparison of instances with the same identity results in equality, and equality comparison of instances with different identities results in inequality. A motivation for this default behavior is the desire that all objects should be reflexive (i.e. x is y implies x == y ).

A default order comparison ( < , > , <= , and >= ) is not provided; an attempt raises TypeError . A motivation for this default behavior is the lack of a similar invariant as for equality.

The behavior of the default equality comparison, that instances with different identities are always unequal, may be in contrast to what types will need that have a sensible definition of object value and value-based equality. Such types will need to customize their comparison behavior, and in fact, a number of built-in types have done that.

The following list describes the comparison behavior of the most important built-in types.

Numbers of built-in numeric types ( Numeric Types — int, float, complex ) and of the standard library types fractions.Fraction and decimal.Decimal can be compared within and across their types, with the restriction that complex numbers do not support order comparison. Within the limits of the types involved, they compare mathematically (algorithmically) correct without loss of precision.

The not-a-number values float('NaN') and decimal.Decimal('NaN') are special. Any ordered comparison of a number to a not-a-number value is false. A counter-intuitive implication is that not-a-number values are not equal to themselves. For example, if x = float('NaN') , 3 < x , x < 3 and x == x are all false, while x != x is true. This behavior is compliant with IEEE 754.

None and NotImplemented are singletons. PEP 8 advises that comparisons for singletons should always be done with is or is not , never the equality operators.

Binary sequences (instances of bytes or bytearray ) can be compared within and across their types. They compare lexicographically using the numeric values of their elements.

Strings (instances of str ) compare lexicographically using the numerical Unicode code points (the result of the built-in function ord() ) of their characters. 3

Strings and binary sequences cannot be directly compared.

Sequences (instances of tuple , list , or range ) can be compared only within each of their types, with the restriction that ranges do not support order comparison. Equality comparison across these types results in inequality, and ordering comparison across these types raises TypeError .

Sequences compare lexicographically using comparison of corresponding elements. The built-in containers typically assume identical objects are equal to themselves. That lets them bypass equality tests for identical objects to improve performance and to maintain their internal invariants.

Lexicographical comparison between built-in collections works as follows:

For two collections to compare equal, they must be of the same type, have the same length, and each pair of corresponding elements must compare equal (for example, [1,2] == (1,2) is false because the type is not the same).

Collections that support order comparison are ordered the same as their first unequal elements (for example, [1,2,x] <= [1,2,y] has the same value as x <= y ). If a corresponding element does not exist, the shorter collection is ordered first (for example, [1,2] < [1,2,3] is true).

Mappings (instances of dict ) compare equal if and only if they have equal (key, value) pairs. Equality comparison of the keys and values enforces reflexivity.

Order comparisons ( < , > , <= , and >= ) raise TypeError .

Sets (instances of set or frozenset ) can be compared within and across their types.

They define order comparison operators to mean subset and superset tests. Those relations do not define total orderings (for example, the two sets {1,2} and {2,3} are not equal, nor subsets of one another, nor supersets of one another). Accordingly, sets are not appropriate arguments for functions which depend on total ordering (for example, min() , max() , and sorted() produce undefined results given a list of sets as inputs).

Comparison of sets enforces reflexivity of its elements.

Most other built-in types have no comparison methods implemented, so they inherit the default comparison behavior.

User-defined classes that customize their comparison behavior should follow some consistency rules, if possible:

Equality comparison should be reflexive. In other words, identical objects should compare equal:

x is y implies x == y

Comparison should be symmetric. In other words, the following expressions should have the same result:

x == y and y == x x != y and y != x x < y and y > x x <= y and y >= x

Comparison should be transitive. The following (non-exhaustive) examples illustrate that:

x > y and y > z implies x > z x < y and y <= z implies x < z

Inverse comparison should result in the boolean negation. In other words, the following expressions should have the same result:

x == y and not x != y x < y and not x >= y (for total ordering) x > y and not x <= y (for total ordering)

The last two expressions apply to totally ordered collections (e.g. to sequences, but not to sets or mappings). See also the total_ordering() decorator.

The hash() result should be consistent with equality. Objects that are equal should either have the same hash value, or be marked as unhashable.

Python does not enforce these consistency rules. In fact, the not-a-number values are an example for not following these rules.

6.10.2. Membership test operations ¶

The operators in and not in test for membership. x in s evaluates to True if x is a member of s , and False otherwise. x not in s returns the negation of x in s . All built-in sequences and set types support this as well as dictionary, for which in tests whether the dictionary has a given key. For container types such as list, tuple, set, frozenset, dict, or collections.deque, the expression x in y is equivalent to any(x is e or x == e for e in y) .

For the string and bytes types, x in y is True if and only if x is a substring of y . An equivalent test is y.find(x) != -1 . Empty strings are always considered to be a substring of any other string, so "" in "abc" will return True .

For user-defined classes which define the __contains__() method, x in y returns True if y.__contains__(x) returns a true value, and False otherwise.

For user-defined classes which do not define __contains__() but do define __iter__() , x in y is True if some value z , for which the expression x is z or x == z is true, is produced while iterating over y . If an exception is raised during the iteration, it is as if in raised that exception.

Lastly, the old-style iteration protocol is tried: if a class defines __getitem__() , x in y is True if and only if there is a non-negative integer index i such that x is y[i] or x == y[i] , and no lower integer index raises the IndexError exception. (If any other exception is raised, it is as if in raised that exception).

The operator not in is defined to have the inverse truth value of in .

6.10.3. Identity comparisons ¶

The operators is and is not test for an object’s identity: x is y is true if and only if x and y are the same object. An Object’s identity is determined using the id() function. x is not y yields the inverse truth value. 4

6.11. Boolean operations ¶

In the context of Boolean operations, and also when expressions are used by control flow statements, the following values are interpreted as false: False , None , numeric zero of all types, and empty strings and containers (including strings, tuples, lists, dictionaries, sets and frozensets). All other values are interpreted as true. User-defined objects can customize their truth value by providing a __bool__() method.

The operator not yields True if its argument is false, False otherwise.

The expression x and y first evaluates x ; if x is false, its value is returned; otherwise, y is evaluated and the resulting value is returned.

The expression x or y first evaluates x ; if x is true, its value is returned; otherwise, y is evaluated and the resulting value is returned.

Note that neither and nor or restrict the value and type they return to False and True , but rather return the last evaluated argument. This is sometimes useful, e.g., if s is a string that should be replaced by a default value if it is empty, the expression s or 'foo' yields the desired value. Because not has to create a new value, it returns a boolean value regardless of the type of its argument (for example, not 'foo' produces False rather than '' .)

6.12. Assignment expressions ¶

An assignment expression (sometimes also called a “named expression” or “walrus”) assigns an expression to an identifier , while also returning the value of the expression .

One common use case is when handling matched regular expressions:

Or, when processing a file stream in chunks:

Assignment expressions must be surrounded by parentheses when used as sub-expressions in slicing, conditional, lambda, keyword-argument, and comprehension-if expressions and in assert and with statements. In all other places where they can be used, parentheses are not required, including in if and while statements.

New in version 3.8: See PEP 572 for more details about assignment expressions.

6.13. Conditional expressions ¶

Conditional expressions (sometimes called a “ternary operator”) have the lowest priority of all Python operations.

The expression x if C else y first evaluates the condition, C rather than x . If C is true, x is evaluated and its value is returned; otherwise, y is evaluated and its value is returned.

See PEP 308 for more details about conditional expressions.

6.14. Lambdas ¶

Lambda expressions (sometimes called lambda forms) are used to create anonymous functions. The expression lambda parameters: expression yields a function object. The unnamed object behaves like a function object defined with:

See section Function definitions for the syntax of parameter lists. Note that functions created with lambda expressions cannot contain statements or annotations.

6.15. Expression lists ¶

Except when part of a list or set display, an expression list containing at least one comma yields a tuple. The length of the tuple is the number of expressions in the list. The expressions are evaluated from left to right.

An asterisk * denotes iterable unpacking . Its operand must be an iterable . The iterable is expanded into a sequence of items, which are included in the new tuple, list, or set, at the site of the unpacking.

New in version 3.5: Iterable unpacking in expression lists, originally proposed by PEP 448 .

The trailing comma is required only to create a single tuple (a.k.a. a singleton ); it is optional in all other cases. A single expression without a trailing comma doesn’t create a tuple, but rather yields the value of that expression. (To create an empty tuple, use an empty pair of parentheses: () .)

6.16. Evaluation order ¶

Python evaluates expressions from left to right. Notice that while evaluating an assignment, the right-hand side is evaluated before the left-hand side.

In the following lines, expressions will be evaluated in the arithmetic order of their suffixes:

6.17. Operator precedence ¶

The following table summarizes the operator precedence in Python, from highest precedence (most binding) to lowest precedence (least binding). Operators in the same box have the same precedence. Unless the syntax is explicitly given, operators are binary. Operators in the same box group left to right (except for exponentiation and conditional expressions, which group from right to left).

Note that comparisons, membership tests, and identity tests, all have the same precedence and have a left-to-right chaining feature as described in the Comparisons section.

While abs(x%y) < abs(y) is true mathematically, for floats it may not be true numerically due to roundoff. For example, and assuming a platform on which a Python float is an IEEE 754 double-precision number, in order that -1e-100 % 1e100 have the same sign as 1e100 , the computed result is -1e-100 + 1e100 , which is numerically exactly equal to 1e100 . The function math.fmod() returns a result whose sign matches the sign of the first argument instead, and so returns -1e-100 in this case. Which approach is more appropriate depends on the application.

If x is very close to an exact integer multiple of y, it’s possible for x//y to be one larger than (x-x%y)//y due to rounding. In such cases, Python returns the latter result, in order to preserve that divmod(x,y)[0] * y + x % y be very close to x .

The Unicode standard distinguishes between code points (e.g. U+0041) and abstract characters (e.g. “LATIN CAPITAL LETTER A”). While most abstract characters in Unicode are only represented using one code point, there is a number of abstract characters that can in addition be represented using a sequence of more than one code point. For example, the abstract character “LATIN CAPITAL LETTER C WITH CEDILLA” can be represented as a single precomposed character at code position U+00C7, or as a sequence of a base character at code position U+0043 (LATIN CAPITAL LETTER C), followed by a combining character at code position U+0327 (COMBINING CEDILLA).

The comparison operators on strings compare at the level of Unicode code points. This may be counter-intuitive to humans. For example, "\u00C7" == "\u0043\u0327" is False , even though both strings represent the same abstract character “LATIN CAPITAL LETTER C WITH CEDILLA”.

To compare strings at the level of abstract characters (that is, in a way intuitive to humans), use unicodedata.normalize() .

Due to automatic garbage-collection, free lists, and the dynamic nature of descriptors, you may notice seemingly unusual behaviour in certain uses of the is operator, like those involving comparisons between instance methods, or constants. Check their documentation for more info.

The power operator ** binds less tightly than an arithmetic or bitwise unary operator on its right, that is, 2**-1 is 0.5 .

The % operator is also used for string formatting; the same precedence applies.

Table of Contents

  • 6.1. Arithmetic conversions
  • 6.2.1. Identifiers (Names)
  • 6.2.2. Literals
  • 6.2.3. Parenthesized forms
  • 6.2.4. Displays for lists, sets and dictionaries
  • 6.2.5. List displays
  • 6.2.6. Set displays
  • 6.2.7. Dictionary displays
  • 6.2.8. Generator expressions
  • 6.2.9.1. Generator-iterator methods
  • 6.2.9.2. Examples
  • 6.2.9.3. Asynchronous generator functions
  • 6.2.9.4. Asynchronous generator-iterator methods
  • 6.3.1. Attribute references
  • 6.3.2. Subscriptions
  • 6.3.3. Slicings
  • 6.3.4. Calls
  • 6.4. Await expression
  • 6.5. The power operator
  • 6.6. Unary arithmetic and bitwise operations
  • 6.7. Binary arithmetic operations
  • 6.8. Shifting operations
  • 6.9. Binary bitwise operations
  • 6.10.1. Value comparisons
  • 6.10.2. Membership test operations
  • 6.10.3. Identity comparisons
  • 6.11. Boolean operations
  • 6.12. Assignment expressions
  • 6.13. Conditional expressions
  • 6.14. Lambdas
  • 6.15. Expression lists
  • 6.16. Evaluation order
  • 6.17. Operator precedence

Previous topic

5. The import system

7. Simple statements

  • Report a Bug
  • Show Source
  • Stack Overflow Public questions & answers
  • Stack Overflow for Teams Where developers & technologists share private knowledge with coworkers
  • Talent Build your employer brand
  • Advertising Reach developers & technologists worldwide
  • Labs The future of collective knowledge sharing
  • About the company

Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Get early access and see previews of new features.

Does Python have a ternary conditional operator?

Is there a ternary conditional operator in Python?

  • conditional-operator

Mateen Ulhaq's user avatar

  • 205 In the Python 3.0 official documentation referenced in a comment above, this is referred to as "conditional_expressions" and is very cryptically defined. That documentation doesn't even include the term "ternary", so you would be hard-pressed to find it via Google unless you knew exactly what to look for. The version 2 documentation is somewhat more helpful and includes a link to "PEP 308" , which includes a lot of interesting historical context related to this question. –  Brent Bradburn Jan 10, 2013 at 5:57
  • 47 "ternary" (having three inputs) is a consequential property of this impelmentation, not a defining property of the concept. eg: SQL has case [...] { when ... then ...} [ else ... ] end for a similar effect but not at all ternary. –  user313114 Dec 15, 2014 at 21:14
  • 19 also ISO/IEC 9899 (the C programming language standard) section 6.5.15 calls it the "the condtitional operator" –  user313114 Dec 15, 2014 at 21:20
  • 17 Wikipedia covers this thoroughly in the article " ?: ". –  HelloGoodbye Jun 9, 2016 at 8:11
  • 18 In the years since nobar's comment the conditional expression documentation has been updated to say Conditional expressions (sometimes called a “ternary operator”)... –  Scott Martin Aug 15, 2018 at 13:25

32 Answers 32

Yes, it was added in version 2.5. The expression syntax is:

First condition is evaluated, then exactly one of either a or b is evaluated and returned based on the Boolean value of condition . If condition evaluates to True , then a is evaluated and returned but b is ignored, or else when b is evaluated and returned but a is ignored.

This allows short-circuiting because when condition is true only a is evaluated and b is not evaluated at all, but when condition is false only b is evaluated and a is not evaluated at all.

For example:

Note that conditionals are an expression , not a statement . This means you can't use statements such as pass , or assignments with = (or "augmented" assignments like += ), within a conditional expression :

(In 3.8 and above, the := "walrus" operator allows simple assignment of values as an expression , which is then compatible with this syntax. But please don't write code like that; it will quickly become very difficult to understand.)

Similarly, because it is an expression, the else part is mandatory :

You can, however, use conditional expressions to assign a variable like so:

Or for example to return a value:

Think of the conditional expression as switching between two values. We can use it when we are in a 'one value or another' situation, where we will do the same thing with the result, regardless of whether the condition is met. We use the expression to compute the value, and then do something with it. If you need to do something different depending on the condition, then use a normal if statement instead.

Keep in mind that it's frowned upon by some Pythonistas for several reasons:

  • The order of the arguments is different from those of the classic condition ? a : b ternary operator from many other languages (such as C , C++ , Go , Perl , Ruby , Java , JavaScript , etc.), which may lead to bugs when people unfamiliar with Python's "surprising" behaviour use it (they may reverse the argument order).
  • Some find it "unwieldy", since it goes contrary to the normal flow of thought (thinking of the condition first and then the effects).
  • Stylistic reasons. (Although the 'inline if ' can be really useful, and make your script more concise, it really does complicate your code)

If you're having trouble remembering the order, then remember that when read aloud, you (almost) say what you mean. For example, x = 4 if b > 8 else 9 is read aloud as x will be 4 if b is greater than 8 otherwise 9 .

Official documentation:

  • Conditional expressions
  • Is there an equivalent of C’s ”?:” ternary operator?

Karl Knechtel's user avatar

  • 355 The order may seems strange for coders however f(x) = |x| = x if x > 0 else -x sounds very natural to mathematicians. You may also understand it as do A in most case, except when C then you should do B instead... –  yota Jan 25, 2016 at 15:07
  • 171 Be careful with order of operations when using this. For example, the line z = 3 + x if x < y else y . If x=2 and y=1 , you might expect that to yield 4, but it would actually yield 1. z = 3 + (x if x > y else y) is the correct usage. –  Kal Zekdor Mar 6, 2016 at 9:23
  • 19 The point was if you want to perform additional evaluations after the conditional is evaluated, like adding a value to the result, you'll either need to add the additional expression to both sides ( z = 3 + x if x < y else 3 + y ), or group the conditional ( z = 3 + (x if x < y else y) or z = (x if x < y else y) + 3 ) –  Kal Zekdor Apr 15, 2016 at 0:36
  • 7 @MrGeek, I see what you mean, so you would basically be nesting the operations: ` "foo" if Bool else ("bar" if Bool else "foobar") ` –  Dimesio Aug 11, 2017 at 0:04
  • 11 Programmers need precise correct formulation even more than mathematician, because in mathematics there is always a resort to underlying concepts. A convincing argument is the % operator, mimicking the way "mod" is used in math would have been a disaster. So no, I don't accept your argument. It is like adhering to imperial units. Groetjes Albert –  Albert van der Horst Jun 17, 2018 at 12:50

You can index into a tuple:

test needs to return True or False . It might be safer to always implement it as:

or you can use the built-in bool() to assure a Boolean value:

jesterjunk's user avatar

  • 722 Note that this one always evaluates everything, whereas the if/else construct only evaluates the winning expression. –  SilverbackNet Feb 4, 2011 at 2:25
  • 143 (lambda: print("a"), lambda: print("b"))[test==true]() –  Dustin Getz Mar 8, 2012 at 19:31
  • 20 It should be noted that what's within the [] s can be an arbitrary expression. Also, for safety you can explicitly test for truthiness by writing [bool(<expression>)] . The bool() function has been around since v2.2.1. –  martineau May 31, 2012 at 18:20
  • 13 I've done a similar trick -- only once or twice, but done it -- by indexing into a dictionary with True and False as the keys: {True:trueValue, False:falseValue}[test] I don't know whether this is any less efficient, but it does at least avoid the whole "elegant" vs. "ugly" debate. There's no ambiguity that you're dealing with a boolean rather than an int. –  JDM Mar 1, 2016 at 18:43
  • 10 comparisons to singletons should always use is/is not instead of == –  Natecat May 2, 2016 at 23:10

For versions prior to 2.5, there's the trick:

It can give wrong results when on_true has a false Boolean value. 1

Although it does have the benefit of evaluating expressions left to right, which is clearer in my opinion.

1. Is there an equivalent of C’s ”?:” ternary operator?

Peter Mortensen's user avatar

  • 77 The remedy is to use (test and [true_value] or [false_value])[0], which avoids this trap. –  ThomasH Oct 21, 2009 at 15:33
  • 8 Ternary operator usually executes faster(sometimes by 10-25%). –  volcano Jan 13, 2014 at 7:52
  • 9 @volcano Do you have source for me? –  OrangeTux Aug 5, 2014 at 12:30
  • 6 @OrangeTux Here's the disassembled code . Using the method ThomasH suggested would be even slower. –  mbomb007 Mar 19, 2018 at 20:59

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

Ed The ''Pro'''s user avatar

  • 95 This one emphasizes the primary intent of the ternary operator: value selection. It also shows that more than one ternary can be chained together into a single expression. –  Roy Tinker Oct 4, 2010 at 21:14
  • 7 @Craig , I agree, but it's also helpful to know what will happen when there are no parentheses. In real code, I too would tend to insert explicit parens. –  Jon Coombs Dec 1, 2014 at 21:30
  • 1 Use: return 3 if t > 10 else t/2 –  mins Oct 25, 2020 at 16:41

From the documentation :

Conditional expressions (sometimes called a “ternary operator”) have the lowest priority of all Python operations. The expression x if C else y first evaluates the condition, C ( not x ); if C is true, x is evaluated and its value is returned; otherwise, y is evaluated and its value is returned. See PEP 308 for more details about conditional expressions.

New since version 2.5.

Michael Burr's user avatar

An operator for a conditional expression in Python was added in 2006 as part of Python Enhancement Proposal 308 . Its form differs from common ?: operator and it looks like this:

which is equivalent to:

Here is an example:

Another syntax which can be used (compatible with versions before 2.5):

where operands are lazily evaluated .

Another way is by indexing a tuple (which isn't consistent with the conditional operator of most other languages):

or explicitly constructed dictionary:

Another (less reliable), but simpler method is to use and and or operators:

however this won't work if x would be False .

A possible workaround is to make x and y lists or tuples as in the following:

If you're working with dictionaries, instead of using a ternary conditional, you can take advantage of get(key, default) , for example:

Source: ?: in Python at Wikipedia

Marc Sances's user avatar

  • 2 result = {1: x, 0: y}[a > b] is another possible variant ( True and False are actually integers with values 1 and 0 ) –  Walter Tross Feb 9, 2019 at 18:07

Unfortunately, the

solution doesn't have short-circuit behaviour; thus both falseValue and trueValue are evaluated regardless of the condition. This could be suboptimal or even buggy (i.e. both trueValue and falseValue could be methods and have side effects).

One solution to this would be

(execution delayed until the winner is known ;)), but it introduces inconsistency between callable and non-callable objects. In addition, it doesn't solve the case when using properties.

And so the story goes - choosing between three mentioned solutions is a trade-off between having the short-circuit feature, using at least Python 2.5 (IMHO, not a problem anymore) and not being prone to " trueValue -evaluates-to-false" errors.

gorsky's user avatar

  • 4 While the tuple of lambdas trick works, it takes roughly 3x as long as the ternary operator. It's only likely to be a reasonable idea if it can replace a long chain of if else if . –  Perkins Oct 11, 2018 at 17:34
  • this is so unreadable compared with the ternary operator –  Neuron Mar 27 at 22:41

Ternary operator in different programming languages

Here I just try to show some important differences in the ternary operator between a couple of programming languages.

Ternary operator in JavaScript

Ternary operator in ruby, ternary operator in scala, ternary operator in r programming, ternary operator in python.

Arun V Jose's user avatar

  • 18 This blogger found python's ternary operator to be unnecessarily different than most other languages . –  JamesThomasMoon Feb 15, 2017 at 23:08
  • 12 It may sound opinionated; but what it essentially says is that it the Python syntax is likely to be understood by a person who never saw a ternary operator, while very few people will understand the more usual syntax unless they have been told first what it means. –  fralau Jan 10, 2018 at 17:12
  • 2 Algol68: a=.if. .true. .then. 1 .else. 0 .fi. This may be expressed also a=(.true.|1|0) As usual Algol68 is an improvement over its successors. –  Albert van der Horst Jun 17, 2018 at 12:55
  • something simple as print a || '<alt text>' in ruby is pita in python print a if a is not None else 'alt text' –  Varun Garg Nov 5, 2020 at 8:44
  • 2 @VarunGarg But of course you can say print(a or 'alt text') in Python. –  lenz Nov 15, 2020 at 20:24

For Python 2.5 and newer there is a specific syntax:

In older Pythons, a ternary operator is not implemented but it's possible to simulate it.

Though there is a potential problem, which is if cond evaluates to True and on_true evaluates to False then on_false is returned instead of on_true . If you want this behaviour the method is OK, otherwise use this:

which can be wrapped by:

and used this way:

It is compatible with all Python versions.

enslaved_programmer's user avatar

  • 4 The behaviour is not identical - q("blob", on_true, on_false) returns on_false , whereas on_true if cond else on_false returns on_true . A workaround is to replace cond with cond is not None in these cases, although that is not a perfect solution. –  user3317 Sep 26, 2012 at 9:09
  • 7 Why not bool(cond) instead of cond is True ? The former checks the truthiness of cond , the latter checks for pointer-equality with the True object. As highlighted by @AndrewCecil, "blob" is truthy but it is not True . –  Jonas Kölker Nov 11, 2013 at 16:11

You might often find

but this leads to a problem when on_true == 0

Where you would expect this result for a normal ternary operator:

Javad's user avatar

Yes. From the grammar file :

The part of interest is:

So, a ternary conditional operation is of the form:

expression3 will be lazily evaluated (that is, evaluated only if expression2 is false in a boolean context). And because of the recursive definition, you can chain them indefinitely (though it may considered bad style.)

A note on usage:

Note that every if must be followed with an else . People learning list comprehensions and generator expressions may find this to be a difficult lesson to learn - the following will not work, as Python expects a third expression for an else:

which raises a SyntaxError: invalid syntax . So the above is either an incomplete piece of logic (perhaps the user expects a no-op in the false condition) or what may be intended is to use expression2 as a filter - notes that the following is legal Python:

expression2 works as a filter for the list comprehension, and is not a ternary conditional operator.

Alternative syntax for a more narrow case:

You may find it somewhat painful to write the following:

expression1 will have to be evaluated twice with the above usage. It can limit redundancy if it is simply a local variable. However, a common and performant Pythonic idiom for this use-case is to use or 's shortcutting behavior:

which is equivalent in semantics. Note that some style-guides may limit this usage on the grounds of clarity - it does pack a lot of meaning into very little syntax.

Russia Must Remove Putin's user avatar

  • 1 expression1 or expression2 being similar and with the same drawbacks/positives as expression1 || expression2 in javascript –  JSDBroughton Feb 18, 2016 at 13:05
  • 1 Thanks, @selurvedu - it can be confusing until you get it straight. I learned the hard way, so your way might not be as hard. ;) Using if without the else, at the end of a generator expression or list comprehension will filter the iterable. In the front, it's a ternary conditional operation, and requires the else. Cheers!! –  Russia Must Remove Putin ♦ May 27, 2016 at 4:37
  • @AaronHall Although your use of metasyntactic expressionN for all instances is consistent, it might be easier to understand with naming that distinguished the conditional test expression from the two result expressions; eg, result1 if condition else result2 . This is especially evident when nesting (aka chaining): result1 if condition1 else result2 if condition2 else result3 . See how much better that reads this way? –  tchrist Jan 26, 2019 at 14:12
  • 1 @tchrist thanks for the review - if you look at the revision history, this post currently has two revisions. Most of my other answers, especially the top ones, have been revisited again and again. This answer never gets my attention because the community wiki status gives me no credit for the content, and so I never see any votes on it. As I don't really have time for an edit on this right now, frog knows when it will come to my attention again in the future. I can see you've edited the top answer, so feel free to borrow/quote my material from this post in that one (and cite me if apropos!) –  Russia Must Remove Putin ♦ Jan 26, 2019 at 18:24

One of the alternatives to Python's conditional expression

is the following:

which has the following nice extension:

The shortest alternative remains

which works because issubclass(bool, int) .

Careful, though: the alternative to

This works fine as long as no and yes are to be called with exactly the same parameters. If they are not, like in

then a similar alternative either does not exist (1) or is hardly viable (2). (In rare cases, depending on the context, something like

could make sense.)

Thanks to Radek Rojík for his comment

Walter Tross's user avatar

As already answered, yes, there is a ternary operator in Python:

In many cases <expression 1> is also used as Boolean evaluated <condition> . Then you can use short-circuit evaluation .

One big pro of short-circuit evaluation is the possibility of chaining more than two expressions:

When working with functions it is more different in detail:

PS: Of course, a short-circuit evaluation is not a ternary operator, but often the ternary is used in cases where the short circuit would be enough. It has a better readability and can be chained.

Frank's user avatar

Simulating the Python ternary operator.

For example

Sasikiran Vaddi's user avatar

  • 1 Why not simply result = (y, x)[a < b] Why do you uses lambda function ? –  Grijesh Chauhan Dec 27, 2013 at 5:50
  • 6 @GrijeshChauhan Because on "compliated" expressions, e. g. involving a function call etc., this would be executed in both cases. This might not be wanted. –  glglgl Feb 13, 2014 at 8:14
  • 2 The use of lambda functions is an overkill for this question –  Jocer Dec 14, 2020 at 4:29
  • @GrijeshChauhan In short, this implements the so-called “ short-circuit evaluation ”. Generally, P ? x : y or x if P else y can be written as (lambda:y, lambda:x)[P]() — but I doubt it has better performance and thus its necessity. –  SnzFor16Min Jan 19, 2021 at 10:11

Just memorize this pyramid if you have trouble remembering:

shivtej's user avatar

Vinko Vrsalovic's answer is good enough. There is only one more thing:

Note that conditionals are an expression , not a statement . This means you can't use assignment statements or pass or other statements within a conditional expression

Walrus operator in Python 3.8

After the walrus operator was introduced in Python 3.8, something changed.

gives a = 3 and b is not defined ,

gives a is not defined and b = 5 , and

gives c = 5 , a is not defined and b = 5 .

Even if this may be ugly, assignments can be done inside conditional expressions after Python 3.8. Anyway, it is still better to use normal if statement instead in this case.

David Chung's user avatar

  • In the first example: (a := 3) if True else (b := 5) actually it's a redundant first walrus operator. This will do: a = 3 if True else (b := 5) –  Andrew Anderson Aug 4, 2021 at 12:48
  • 2 @AndrewAnderson No it's not redundant. You should compare both the first and the second examples. You can combine them and consider this: (a := 3) if x else (b := 5) , you always get either a or b assigned, not both. However, consider a = 3 if x else (b := 5) , when x == False , you will get a = 5 and b = 5 , where both them are assigned. –  Ddavid Aug 5, 2021 at 15:36
  • Yes, that's correct :). I considered this only for x=True case which is of course is limited. –  Andrew Anderson Aug 6, 2021 at 11:56
  • Because we don't really write down this code if True else , the reason of the first example is only compared with other examples. –  Ddavid Aug 7, 2021 at 12:30

The ternary conditional operator simply allows testing a condition in a single line replacing the multiline if-else making the code compact.

[on_true] if [expression] else [on_false]

1- Simple Method to use ternary operator:

2- direct method of using tuples, dictionary, and lambda:, 3- ternary operator can be written as nested if-else:.

Above approach can be written as:

Ali Hallaji's user avatar

  • 1 Note that the ternary operator is smaller (in memory) and faster than the nested if. Also, your nested if-else isn't actually a rewrite of the ternary operator, and will produce different output for select values of a and b (specifically if one is a type which implements a weird __ne__ method). –  Perkins Oct 11, 2018 at 17:28

More a tip than an answer (I don't need to repeat the obvious for the hundredth time), but I sometimes use it as a one-liner shortcut in such constructs:

Some (many :) may frown upon it as unpythonic (even, Ruby-ish :), but I personally find it more natural - i.e., how you'd express it normally, plus a bit more visually appealing in large blocks of code.

Todor Minakov's user avatar

  • 8 I prefer print( 'yes' if conditionX else 'nah' ) over your answer. :-) –  frederick99 Aug 20, 2017 at 6:07
  • 1 That is if you want to print() in both cases - and it looks a bit more pythonic, I have to admit :) But what if the expressions/functions are not the same - like print('yes') if conditionX else True - to get the print() only in truthy conditionX –  Todor Minakov Oct 26, 2017 at 11:40
  • To add to Frederick99's remark, another reason to avoid print('yes') if conditionX else print('nah') is that it gives a SyntaxError in Python2. –  Thierry Lathuille Oct 21, 2018 at 21:51
  • The only reason it gives a syntax error is because in Python 2 print is a statement - print "yes" , while in Python 3 it is a function - print("yes") . That can be resolved by either using it as a statement, or better - from future import print_function . –  Todor Minakov Oct 22, 2018 at 4:09

You can do this:

This would print "odd" if the number is odd or "even" if the number is even.

The result: If condition is true, exp_1 is executed, else exp_2 is executed.

Note: 0, None, False, emptylist, and emptyString evaluates as False.

And any data other than 0 evaluates to True.

Here's how it works:

If the condition [condition] becomes "True", then expression_1 will be evaluated, but not expression_2.

If we "and" something with 0 (zero), the result will always to be false. So in the below statement,

The expression exp won't be evaluated at all since "and" with 0 will always evaluate to zero and there is no need to evaluate the expression. This is how the compiler itself works, in all languages.

the expression exp won't be evaluated at all since "or" with 1 will always be 1. So it won't bother to evaluate the expression exp since the result will be 1 anyway (compiler optimization methods).

But in case of

The second expression exp2 won't be evaluated since True and exp1 would be True when exp1 isn't false.

Similarly in

The expression exp1 won't be evaluated since False is equivalent to writing 0 and doing "and" with 0 would be 0 itself, but after exp1 since "or" is used, it will evaluate the expression exp2 after "or".

Note:- This kind of branching using "or" and "and" can only be used when the expression_1 doesn't have a Truth value of False (or 0 or None or emptylist [ ] or emptystring ' '.) since if expression_1 becomes False, then the expression_2 will be evaluated because of the presence "or" between exp_1 and exp_2.

In case you still want to make it work for all the cases regardless of what exp_1 and exp_2 truth values are, do this:

Natesh bhat's user avatar

  • If you want to use that in the context of x = [condition] and ([expression_1] or 1) or [expression_2] and expression_1 evaluates to false, x will be 1 , not expression_1 . Use the accepted answer. –  moi Oct 20, 2017 at 6:37

Many programming languages derived from C usually have the following syntax of the ternary conditional operator:

At first, the Python's benevolent dictator for life (I mean Guido van Rossum , of course) rejected it (as non-Pythonic style), since it's quite hard to understand for people not used to C language. Also, the colon sign : already has many uses in Python. After PEP 308 was approved, Python finally received its own shortcut conditional expression (what we use now):

So, firstly it evaluates the condition. If it returns True , expression1 will be evaluated to give the result, otherwise expression2 will be evaluated. Due to lazy evaluation mechanics – only one expression will be executed.

Here are some examples (conditions will be evaluated from left to right):

Ternary operators can be chained in series:

The following one is the same as previous one:

Andy Jazz's user avatar

Yes , Python have a ternary operator, here is the syntax and an example code to demonstrate the same :)

realmanusharma's user avatar

  • I have added a one line statement example to check which number is big to elaborate it further –  realmanusharma Oct 21, 2018 at 20:45
  • 1 print is really not a good choice, as this will give a SyntaxError in Python2. –  Thierry Lathuille Oct 21, 2018 at 21:52
  • @Thierry Lathuille here I used print() function not print statement, print function is for Python 3 while print statement is for Python 2 –  realmanusharma Oct 21, 2018 at 21:54
  • The question has already been asked on SO, just try it with Python 2 and you will see by yourself. 'print('hello') is a perfectly valid syntax in Python 2.7, but the way it is parsed makes your code above throw a SyntaxError. –  Thierry Lathuille Oct 21, 2018 at 21:58

Other answers correctly talk about the Python ternary operator. I would like to complement by mentioning a scenario for which the ternary operator is often used, but for which there is a better idiom. This is the scenario of using a default value.

Suppose we want to use option_value with a default value if it is not set:

or, if option_value is never set to a falsy value ( 0 , "" , etc.), simply

However, in this case an ever better solution is simply to write

user118967's user avatar

  • 5 A valuable complement, but I disagree: option_value or 10 is not better than option_value if option_value is not None else 10 . It is shorter, indeed, but looks weird to me and may lead to bugs. What happens if option_value = 0 , for instance? The first snippet will run run_algorithm(0) because option_value is not None . The second and third snippets, however, will run run_algorithm(10) because 0 is a falsy. The two snippets are not equivalent, and hence one is not better than the other. And explicit is better than implicit. –  ruancomelli Oct 20, 2020 at 15:21
  • @ruancomelli: Good point. I've modified the answer to reflect that correction. –  user118967 Oct 22, 2020 at 14:04
  • 4 As for it looking weird, I wonder if it looked weird to you because you noticed the imprecision (that it was not really equivalent). To me it sounds natural because it reminds me saying in English: "Use this or that (if the first option is unavailable)". But of course that is subjective. It is useful to know it does not look natural to everybody. –  user118967 Oct 22, 2020 at 14:06
  • 2 Much better! And thanks for the explanation regarding the "or"-idiom. It looks weird to me because I tend to think of or as a function mapping two arguments to a boolean, so I expect it to return either True or False (this happens in many other programming languages). But "use this or that" is a nice mnemonic and will definitely help me (and hopefully others) to remember this pattern. –  ruancomelli Oct 28, 2020 at 19:44

The syntax for the ternary operator in Python is:

Using that syntax, here is how we would rewrite the code above using Python’s ternary operator:

It's still pretty clear, but much shorter. Note that the expression could be any type of expression, including a function call, that returns a value that evaluates to True or False.

George Imerlishvili's user avatar

Python has a ternary form for assignments; however there may be even a shorter form that people should be aware of.

It's very common to need to assign to a variable one value or another depending on a condition.

^ This is the long form for doing such assignments.

Below is the ternary form. But this isn't the most succinct way - see the last example.

With Python, you can simply use or for alternative assignments.

The above works since li1 is None and the interpreter treats that as False in logic expressions. The interpreter then moves on and evaluates the second expression, which is not None and it's not an empty list - so it gets assigned to a .

This also works with empty lists. For instance, if you want to assign a whichever list has items.

Knowing this, you can simply such assignments whenever you encounter them. This also works with strings and other iterables. You could assign a whichever string isn't empty.

I always liked the C ternary syntax, but Python takes it a step further!

I understand that some may say this isn't a good stylistic choice, because it relies on mechanics that aren't immediately apparent to all developers. I personally disagree with that viewpoint. Python is a syntax-rich language with lots of idiomatic tricks that aren't immediately apparent to the dabbler. But the more you learn and understand the mechanics of the underlying system, the more you appreciate it.

Todd's user avatar

  • Something seems to be missing near "simply such assignments" . –  Peter Mortensen Feb 6, 2022 at 13:27
  • "Simplify" such assignments =) @PeterMortensen –  Todd Feb 6, 2022 at 16:17
  • Very interesting! Two questions: 1) Clearly, if exactly one of li1 and li2 is truthy, then li1 or li2 will return its value. If bool(li1) returns the same value as bool(li2) , will li1 or li2 consistently evaluate to be either one or the other (perhabs by position)? 2) how can you interpret what returns from li1 and li2 ? I can't make sense of it with my test cases. –  TimH Oct 20, 2022 at 4:20
  • 1 @TimH: 1) The right hand or subexpressions of the assignment are interpreted left to right. If the first one is truthy, that's the one that gets assigned to the var. If it isn't truthy, the second one is assigned. 2) using the and operation wouldn't be like some sort of ternary operation as this answer discusses. –  Todd Oct 31, 2022 at 7:33

Pythonic way of doing the things:

But there always exists a different way of doing a ternary condition too:

Franz Gastring's user avatar

There are multiple ways. The simplest one is to use the condition inside the "print" method.

You can use

Which is equivalent to:

In this way, more than two statements are also possible to print. For example:

can be written as:

Aldrin Saurov Sarker's user avatar

The if else-if version can be written as:

DevLoverUmar's user avatar

Yes, it has, but it's different from C-syntax-like programming languages (which is condition ? value_if_true : value_if_false

In Python, it goes like this: value_if_true if condition else value_if_false

Example: even_or_odd = "even" if x % 2 == 0 else "odd"

Heroes Of Balkan's user avatar

A neat way to chain multiple operators:

Yaakov Bressler's user avatar

Yes, Python has a ternary conditional operator, also known as the conditional expression or the ternary operator. The syntax of the ternary operator in Python is:

Here's an example to illustrate its usage:

In this example, the condition x % 2 == 0 checks if x is divisible by 2. If the condition is True, the value "Even" is assigned to the variable result. Otherwise, the value "Odd" is assigned. The output will be:

It is a good idea to use parenthesis, in order to increase readability, when working with medium complexity operations:

Instead of:

The ternary operator is a concise way to write simple conditional expressions in a single line. It can be particularly useful when assigning values or constructing expressions based on conditions. However, for more complex conditions or longer expressions, if possible it's generally better to use if-else statements for improved readability.

PhPires13's user avatar

Not the answer you're looking for? Browse other questions tagged python operators conditional-operator or ask your own question .

  • The Overflow Blog
  • Like Python++ for AI developers
  • Being creative with math: The immersive artist who traded a sketchpad for a...
  • Featured on Meta
  • Alpha test for short survey in banner ad slots starting on week of September...
  • What should be next for community events?
  • OverflowAI Search is now available for alpha testing (September 13, 2023)
  • Temporary policy: Generative AI (e.g., ChatGPT) is banned
  • Expanding Discussions: Let's talk about curation
  • Update on Collectives and Discussions

Hot Network Questions

  • Make custard firmer
  • Can the collapse of the wave function be modelled as a quantum system on its own?
  • How can I unclog a sink when the drain stopper cannot be removed?
  • general principles of piercing the protective cover of unfrozen microwave ready meals
  • How to remove one piece of a pelmet
  • Book of short stories I read as a kid; one story about a starving girl, one about a boy who stays forever young
  • What should I do if I am strongly burned out at work, but resigning now would cause problems for my coworkers and burn bridges?
  • Does Sonoma encrypt a disk without asking?
  • Super soldier thief hired to steal vase of incredible beauty
  • What is mode borrowing?
  • Geometric Algebra
  • How can do you learn about residential sprinkler systems in the US?
  • Is it possible to redefine the limit operator to print Lim, not lim?
  • Why would people join a bloc party?
  • How does the Boeing TTBW reduce fuel consumption?
  • What was the big pillar-shaped Beholder in 3.5?
  • How to strip 32 AWG wires for small connectors with ~1mm a wire length
  • How to check if at least one ordering of the given row matches one of the rows of a table?
  • Iteration counts of AMG solver changes in parallel
  • What is this unusual syntax for the Commodore SYS command?
  • My husband (her father) jokes/plays in ways my daughter doesn't always find funny, he says he should be able to do it if he wants
  • Creating a new language with Rust without Garbage Collection?
  • How to commutate high voltage by low voltage transistor?
  • What is the nature of a hexblood's "irremovable living crown"?

python conditional expression order

Your privacy

By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy .

note.nkmk.me

Conditional expression (ternary operator) in python.

Python has a conditional expression (sometimes called a "ternary operator"). You can write operations like if statements in one line with conditional expressions.

  • 6. Expressions - Conditional expressions — Python 3.11.3 documentation

Basics of the conditional expression (ternary operator)

If ... elif ... else ... by conditional expressions, list comprehensions and conditional expressions, lambda expressions and conditional expressions.

See the following article for if statements in Python.

  • Python if statements (if, elif, else)

In Python, the conditional expression is written as follows.

The condition is evaluated first. If condition is True , X is evaluated and its value is returned, and if condition is False , Y is evaluated and its value is returned.

If you want to switch the value based on a condition, simply use the desired values in the conditional expression.

If you want to switch between operations based on a condition, simply describe each corresponding expression in the conditional expression.

An expression that does not return a value (i.e., an expression that returns None ) is also acceptable in a conditional expression. Depending on the condition, either expression will be evaluated and executed.

The above example is equivalent to the following code written with an if statement.

You can also combine multiple conditions using logical operators such as and or or .

  • Boolean operators in Python (and, or, not)

By combining conditional expressions, you can write an operation like if ... elif ... else ... in one line.

However, it is difficult to understand, so it may be better not to use it often.

The following two interpretations are possible, but the expression is processed as the first one.

In the sample code below, which includes three expressions, the first expression is interpreted like the second, rather than the third:

By using conditional expressions in list comprehensions, you can apply operations to the elements of the list based on the condition.

See the following article for details on list comprehensions.

  • List comprehensions in Python

Conditional expressions are also useful when you want to apply an operation similar to an if statement within lambda expressions.

In the example above, the lambda expression is assigned to a variable for convenience, but this is not recommended by PEP8.

Refer to the following article for more details on lambda expressions.

  • Lambda expressions in Python

Related Categories

Related articles.

  • Convert between Unix time (Epoch time) and datetime in Python
  • Default parameter values for functions in Python
  • Composite two images according to a mask image with Python, Pillow
  • NumPy: Rotate array (np.rot90)
  • Get the length of a string (number of characters) in Python
  • The assert statement in Python
  • pandas: Add rows/columns to DataFrame with assign(), insert()
  • NumPy: Limit ndarray values to min and max with clip()
  • pandas: Extract columns from DataFrame based on dtype
  • Count the number of 1 bits in python (int.bit_count)
  • Get and change the current working directory in Python
  • Read, write, and create files in Python (with and open())
  • NumPy: Round up/down the elements of a ndarray (np.floor, trunc, ceil)
  • Try, except, else, finally in Python (Exception handling)

IMAGES

  1. Python Conditional Statements: IF…Else, ELIF & Switch Case (2023)

    python conditional expression order

  2. Python Conditional Statements: IF…Else, ELIF & Switch Case (2022)

    python conditional expression order

  3. Conditional Statements in Python

    python conditional expression order

  4. Python IF, ELSE, ELIF, Nested IF & Switch Case Statement

    python conditional expression order

  5. Conditionals in Python

    python conditional expression order

  6. Conditional Statements and Indentation in Python

    python conditional expression order

VIDEO

  1. Python Conditional Statement in Telugu

  2. Python Conditional Statements

  3. Python-Conditional Execution

  4. how to implement if conditional statement in python #shorts #python #pythontricks #ifstatementpython

  5. Python -Conditional Statements

  6. ''Conditional Statements and Loops in Python'' Python Programming lecture 02 By Mr Manoj Kumar, AKG

COMMENTS

  1. In which order is an if statement evaluated in Python

    5 Answers Sorted by: 67 The left clause will be evaluated first, and then the right one only if the first one is False. This is why you can do stuff like: if not person or person.name == 'Bob': print "You have to select a person and it can't be Bob" Without it breaking.

  2. Conditional Statements in Python

    It allows for conditional execution of a statement or group of statements based on the value of an expression. The outline of this tutorial is as follows: First, you’ll get a quick overview of the if statement in its simplest form.

  3. 6. Expressions

    2 Answers Sorted by: 3 Python evaluates boolean conditions lazily. So your code is safe as if statement will check your string existence first. From docs: The expression x and y first evaluates x; if x is false, its value is returned; otherwise, y is evaluated and the resulting value is returned.

  4. Does Python have a ternary conditional operator?

    In the Python 3.0 official documentation referenced in a comment above, this is referred to as "conditional_expressions" and is very cryptically defined. That documentation doesn't even include the term "ternary", so you would be hard-pressed to find it via Google unless you knew exactly what to look for.

  5. Conditional expression (ternary operator) in Python

    Python has a conditional expression (sometimes called a "ternary operator"). You can write operations like if statements in one line with conditional expressions. 6. Expressions - Conditional expressions — Python 3.11.3 documentation Contents Basics of the conditional expression (ternary operator) if ... elif ... else ... by conditional expressions