Proper Way to Shift Integer Into List Index Range

Question:

I need to retrieve the item at index i from list l. However, sometimes i falls outside of the range of the list index and throws an IndexError. I need to shift i to always be inside the range of the list index by leaps of len(l). The following code achieves just that.

l = ['a', 'b', 'c', 'd', 'e']

i = 6

while i >= len(l):
    i -= len(l)
while i < 0:
    i += len(l)

item = l[i] # item = 'b'

For my use case, i never falls more than len(l) out of range in either direction, so I’m able to shorten to this one liner by using if statements instead of while statements.

l = ['a', 'b', 'c', 'd', 'e']

i = -3

i = i-len(l) if i >= len(l) else i+len(l) if i < 0 else i

item = l[i] # item = 'c'

I’m thinking there must be some builtin function that achieves just this result, without a long, logical sentence. Is there a proper way to do this?

Asked By: MillerTime

||

Answers:

No, there’s no built-in function to do this. But it’s simple to create one.

def clamp(x, size):
    return max(0, min(x, size-1))
Answered By: Mark Ransom

How about i = max(0, min(i, len(lst)-1))

lst = list(range(5))

i = 25
i = max(0, min(i, len(lst)-1))
print(lst[i])

i = -25
i = max(0, min(i, len(lst)-1))
print(lst[i])

Output

4
0
Answered By: Mortz

Seems like a perfect use case for the modulo operator.

item = l[i % len(l)]
Answered By: 0x5453
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.