for i in range(0,len(A) - 1):
cand = (A[i] A[i 1]) / 2
cand2 = i 2 < len(A) and (A[i] A[i 1] A[i 2]) / 3 or cand
A[i] = min(cand, cand2)
I've written the above code to compute the minimum average of the next two & three elements of an integer array. For example, if we have the array [2,3,5,6]
, on the first iteration cand
will be 2.5
and cand2
will be 3.33
so A[0]
will be updated to 2.5
and so on.
This code works, except when (A[i] A[i 1] A[i 2]) / 3
is 0
. In this case, the or
statement executes and cand2
gets set to cand
.
I'm pretty sure this is because Python interprets the 0
as False
and executes the or
statement - how can I fix this though?
CodePudding user response:
It seems you wanted to do a ternary if here, that would work like this:
for i in range(0,len(A) - 1):
cand = (A[i] A[i 1]) / 2
cand2 = (A[i] A[i 1] A[i 2]) / 3 if i 2 < len(A) else cand
A[i] = min(cand, cand2)
You chained them with boolean operators, which maybe can work, as in python they do some tricks (an and
-chained expression will return the first Falsy value of the chain, or the last value if all are Truthy - - - an or
-chained expression will return the first Truthy value or the value if all are Falsy), but that makes your program a lot harder to understand.
Anyway, you might want to consider using a regular if
construct here for best readability.
- The if branch should be the most likely one.
- Don’t use nested ternary operators (use plain multi-line if ... elif > ... then ... statements instead).
- Don’t use long ternary operators with complicated expressions (again use multi-line if statements instead).
for i in range(0,len(A) - 1):
cand = (A[i] A[i 1]) / 2
if i 2 < len(A):
cand2 = (A[i] A[i 1] A[i 2]) / 3
else:
cand2 = cand
A[i] = min(cand, cand2)