Use of _ in range

I am trying to solve a problem using classes to convert an integer to a roman numeral
This is the code

class py_solution:
    def int_to_Roman(self, num):
        val = [
            1000, 900, 500, 400,
            100, 90, 50, 40,
            10, 9, 5, 4,
        syb = [
            "M", "CM", "D", "CD",
            "C", "XC", "L", "XL",
            "X", "IX", "V", "IV",
        roman_num = ''
        i = 0
        while  num > 0:
            for _ in range(num // val[i]):
                roman_num += syb[i]
                num -= val[i]
            i += 1
        return roman_num


What is the use of _ in the range statement after for

for _ in range(num // val[i]):


I am trying to look for exercises on classes, where can l find with comments for better understanding…


Using for _ in range(num) is usually just to indicate that the variable doesn’t matter from a conventional standpoint. It has some functions outside of this scenario but here it’s mostly a convention to signal that the loop variable is irrelevant.

For example, if I wanted to print the numbers from 1-10, I could do

for i in range(10):
   print(i + 1)

and this would do the job. Here i is used inside the loop to actually return the values that we require. However in your example, i is not used at all, the for loop is simply there to make the code inside return a set number of times, the actual variable doesn’t matter. Therefore rather than defining a variable, we simply use “_” to allow the loop to be run and identify that we don’t need the variable to be used in the function.

There’s no fundamental difference here as technically if you do print(_) it will still act like a variable and print whatever value it has taken, but it’s a visual indication that the variable is irrelevant to the calculation taking place inside the loop, just like the convention that nested loops use the variables i, j, k etc instead of starting from a, b, c and so on, It’s just a programming convention that lets us see what’s going on in the code without having to think about it as much.

You can find some info on the other special uses of “_” here, which pretty cleanly details when we’d use it and why.

1 Like

so basically l can just remove the for statement, cause its irrelevant, cause am struggling to understand this code

The for is still needed or else you won’t have a loop. _ is just another variable name such as :

num = 5
word = "cucumber"
a = 'a'

But as @adamgaffney96 stated the name _ typically indicates you won’t be using the variable in your loop.

Not quite. The for statement is required for the code to work, as it is what is actually doing the calculation to translate into roman numerals. The most important part from your question is to understand that _ is just a variable like any other you put in that for loop, its use here is purely a visual indication that the variable is not required for use inside the loop. However the other parts working inside the for loop are required, just not the iterator.

I have two questions:

  1. if the loop variable is irrelevant the calculation inside the range function is too or?
  1. why when num = 1 these two lines are skipped


For 1. to clarify the loop as a whole is not irrelevant. What the _ specifically means is this:

When the iterator is set to “_” it means that the iterator is not used within the loop and can be ignored by the developer.

However this does not mean it is ignored by the program, it still functions as a normal loop and the program still requires the loop to be run. This is a purely visual point to demonstrate to future developers that the value of the iterator is not used within the loop, and it is purely for running the same code a set number of times. Therefore if there is a bug in the loop code, it is not related to the value of the iterator.

For 2., the reason the for loop code is skipped is because of how the loop is working. It runs for each number in range(num // val[i]). When num = 1, we have

range(1 // val[i])

Now in python, the // operator does an integer division, which means that you won’t get decimal numbers. This has the knock-on effect meaning that for any division where num < val[i], the value will be 0, since any number less than 1 will be set to 0 by the // operator. Therefore when num = 1, for all values in val[i], we will get

for _ in range(0):
   # code here

where range(0, 0) is just null. Therefore there’s nothing to loop through and as such the loop is skipped. For completeness when val[i] = 1 the code will run, as range(1) is just the number 0, and so the code will run a single time.

Hopefully this explains everything well to you, ask if you have any other questions!