A very common need is to iterate over all indexes into a list, or more generally, iterate from 0 up to (but not including) some limit or count. It's tempting to use range(0, count-1)
for this, but therein lies a gotcha: if count
is zero, then this will be range(0, -1)
, which in MiniScript returns [0, -1]
rather than an empty list.
Fortunately, MiniScript has two easy solutions.
Use .indexes
If your need is actually to iterate over the indexes of some list โ let's call it seq
โ then don't use range(0, seq.len-1)
; instead just use seq.indexes
.
seq = [1,2,3,5,7,11]
for i in seq.indexes
print "Elem " + i + " is " + seq[i]
end for
This is less to type, quick to read, and more clearly expresses your intention. It's also very MiniScript-idiomatic!
Use range(0, count-1, 1)
The third parameter to range
is the step value. If you don't supply a value for this parameter, then it will default to 1 if the end value is greater than the start value, and -1 if it's lesser. This is how you can count down from 10 to 1 just by doing range(10, 1)
. But it's also why range(0, -1)
returns [0, -1]
.
However, if you simply specify a step value of 1, then any time the end value is less than the start value, you'll get an empty list!
count = input("Count how many? ").val
for i in range(0, count-1, 1)
print i
end for
This is a safe way to express "I definitely want a range of numbers that increase as I go, never decrease, no matter what my start and end values are." And it's perfect when the end point of your range depends on some variable, like count - 1
.
Bonus tip: iterating over very large ranges
Doing the Advent of Code contest this year, there have been a couple times where my attempt to use range
in a for
loop failed with a "list too large" error. For example:
for i in range(1, 1E9)
if sqrt(i) % 7 == 0 then result += 1
end for
...produces:
Runtime Error: list too large [line 1]
In such a case, simply switch from a for
loop to a while
loop. Just remember to increment your loop variable, or you'll create an infinite loop!
i = 1
while i < 1E9
if sqrt(i) % 7 == 0 then result += 1
i += 1
end while
Got any other tips for iterating over some range of numbers? Let us know in the comments below!