Here is a simplified example of my problem. I thought that these functions would have exactly the same behavior:
def f1(l):
if type(l[0][0])==list: f=lambda x:x[0][0]
else: f=lambda x:x[0]
l.sort(key=f,reverse=True)
def f2(l):
f=lambda x:x[0][0] if type(l[0][0])==list else lambda x:x[0]
l.sort(key=f,reverse=True)
l=[[1,2],[3,4]]
But in reality f1(l)
works fine when f2(l)
collapses with the exception:
IndexError: list index out of range
So the question is why is it so and is it possible to use ternary operator that returns one of the functions at all?
Nope, you can only assign values when doing ternary operations, not execute functions.
The conditional (ternary) operator is the only JavaScript operator that takes three operands: a condition followed by a question mark ( ? ), then an expression to execute if the condition is truthy followed by a colon ( : ), and finally the expression to execute if the condition is falsy.
There's a different emphasis: An if / else statement emphasises the branching first and what's to be done is secondary, while a ternary operator emphasises what's to be done over the selection of the values to do it with.
In the above syntax, we have tested 2 conditions in a single statement using the ternary operator. In the syntax, if condition1 is incorrect then Expression3 will be executed else if condition1 is correct then the output depends on the condition2.
lambda
has the lowest precedence among operators. This is why Python parses that line as
f = lambda x: (x[0][0] if type(l[0][0]) == list else lambda x: x[0])
The fix is to wrap individual lambda
s in parentheses:
f = (lambda x: x[0][0]) if type(l[0][0]) == list else (lambda x: x[0])
That said, type(l[0][0]) == list
is kinda wrong, isinstance(l[0][0], list)
would be the best way (it also handles subclasses of list
).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With