Code like this
def IsEven(n):
if n%2==0:
return "Is even"
else:
return "Is odd"
can be converted to a function like this
def isEven(n):
return ["Is even","Is odd"][n%2==0]
The question is if code like this:
def intervalsToOutput(n):
intervals=[(x1,x2), (x3,x4), (x5,x6), ... (xn,xn 1)]
if x1<=n<=x2:
return "in first interval"
elif x3<=n<=x4:
return "in second interval"
elif x5<=n<=x6:
return "in third interval"
...
elif xn<=n<=xn 1:
return "in last interval"
... can be replaced efficiently with a function like this:
(assuming the intervals (xi,xi 1) are not overlapping, and are sorted by xi)
def intervalsToOutput(n):
intervals=[(x1,x2), (x3,x4), (x5,x6), ... (xn,xn 1)]
answer=["in first interval","in second interval","in third interval",...,"in last interval"]
retrurn answer[index of (n in Interval)]
The best I made (looking for speed) is
def intervalsToOutput(n):
intervals=[(x1,x2), (x3,x4), (x5,x6), ... (xn,xn 1)]
answer=["in first interval","in second interval","in third interval",...,"in last interval"]
import bisect as bisect
return answer[bisect.bisect_left(intervals, (n, )) - 1]# -1 because it is a zero based list
What bisect_left does is to find the position of n in intervals (in O(log(n)) time) by comparing (n,) with (xn,xn 1)
But the purpose of bisect is to find the insertion place, so it fails for any n which is x_{i 1}<n<=x_{j}
... (x_i, x_{i 1}), (x_j, x_{j 1}) ...
[x_i______x_i 1] fails on this interval x_j [________x_j 1]
CodePudding user response:
Are the intervals random? i.e. if the range is 0-10 and each there are 5 intervals (0-2)(2-4)(4-6)(6-8)(8-10)
Just do something like
def func(n):
spacing = 2
return n // 2
CodePudding user response:
I would do this:
intervals=[(1,2),(6,8),(22,45),(101,110)]
tgt=27
idx=next(i for i,t in enumerate(intervals) if t[0]<=tgt<=t[1])
>>> idx
2
If you want to catch a not-found condition, either use try / except
:
try:
idx=next(i for i,t in enumerate(intervals) if t[0]<=tgt<=t[1])
except StopIteration:
# not found
Or use the default form of next
:
idx=next((i for i,t in enumerate(intervals) if t[0]<=tgt<=t[1]), None)
CodePudding user response:
Well here's one way, but don't do this (for readability, and probably performance). You should really just chain if
,elif
,andelse
statements (or use a for
loop):
def really_esoteric(n):
return ["first", "second", "n"][
[n in range(0,10),
n in range(11,16),
n in range(16,30)].index(True)
]
REPL:
>>> really_esoteric(5)
'first'
>>> really_esoteric(13)
'second'
>>> really_esoteric(20)
'n'