15

One more tip - if anyone is learning Python on HackerRank, knowing this is critical for starting out.

I'm trying to understand this code:

    stamps = set()
    for _ in range(int(input())):
        print('underscore is', _)
        stamps.add(raw_input().strip())
        print(stamps)

Output:

    >>>2 
    underscore is 0
    >>>first
    set(['first'])
    underscore is 1
    >>>second
    set(['second', 'first'])
  1. I put 2 as the first raw input. How does the function know that I'm only looping twice? This is throwing me off because it isn't the typical...for i in xrange(0,2) structure.

  2. At first my thinking was the underscore repeats the last command in shell. So I added print statements in the code to see the value of underscore...but the values just show the 0 and 1, like the typical loop structure.

I read through this post already and I still can't understand which of those 3 usages of underscore is being used.

What is the purpose of the single underscore "_" variable in Python?

I'm just starting to learn Python so easy explanations would be much appreciated!

Antti Haapala
  • 117,318
  • 21
  • 243
  • 279
jhub1
  • 501
  • 3
  • 6
  • 17
  • 1
    underscore is just another variable in this program just like `my_silly_variable`, nothing special. In interactive interpreter the *result* of previous expression is stored into `_`, but otherwise it is still like an ordinary variable, only one whose value the **interactive interpreter** sets before each `>>> ` prompt. – Antti Haapala Aug 28 '16 at 07:14

4 Answers4

31

ncoghlan's answer lists 3 conventional uses for _ in Python:

  1. To hold the result of the last executed statement in an interactive interpreter session. This precedent was set by the standard CPython interpreter, and other interpreters have followed suit
  2. For translation lookup in i18n (imported from the corresponding C conventions, I believe), as in code like:

    raise forms.ValidationError(_("Please enter a correct username"))`
    
  3. As a general purpose "throwaway" variable name to indicate that part of a function result is being deliberately ignored, as in code like:

     label, has_label, _ = text.partition(':')
    

Your question is which one of these is being used in the example in your code. The answer would be that is a throwaway variable (case 3), but its contents are printed here for debugging purposes.

It is however not a general Python convention to use _ as a loop variable if its value is used in any way. Thus you regularly might see:

 for _ in range(10):
     print("Hello world")

where _ immediately signals the reader that the value is not important and it the loop is just repeated 10 times.

However in a code such as

 for i in range(10):
     do_something(i)

where the value of the loop variable is used, it is the convention to use a variable name such as i, j instead of _.

Community
  • 1
  • 1
Antti Haapala
  • 117,318
  • 21
  • 243
  • 279
  • Ok so just to be clear - when the raw_input is used within the range function...the FIRST input value sets the range. The subsequent user inputs simply loops based on the first value that was given. I think my confusion comes from why the range value doesn't change if I just keep putting in numbers 2, 5, etc. No matter what numbers are inputted, the range is set at the value of the first input. – jhub1 Aug 28 '16 at 07:42
  • FWIW, Nick Coghlan is a major core Python developer, so he knows what he's talking about. ;) – PM 2Ring Feb 06 '17 at 02:07
3

For anyone that is trying to understand how underscore and input works in a loop - after spending quite sometime debugging and printing - here's the code that made me understand what was going on.

    for _ in range(int(raw_input())):
        print raw_input()

User input:

    2
    Dog
    Cat

Output:

    # no output despite entering 2, but 2 is set as range - loops 2 times
    Dog
    Cat

Bonus - notice how there's an int() conversion for the first line in the for loop?

The first input is 2, so int() converts that just fine. You can tell the first line of code is being ignored now because putting the second input, 'Dog', through int() would yield an error. Can't words into integer numbers.

jhub1
  • 501
  • 3
  • 6
  • 17
  • I'm not so sure how you can derive the use of `_` here. The first raw_input is not printed because, well, you don't *print* it. For the others, you do. – Jongware Feb 06 '17 at 02:04
1

The underscore is like a normal variable in your program.

grouser
  • 586
  • 7
  • 21
  • 2
    No. It is not a normal variable. First, it is read-only. So, it cannot be used as an lvalue (left hand side of an assignment operation). Secondly, it can be used only when Python is invoked in interactive (command line) mode. – Seshadri R Aug 09 '17 at 06:01
  • @SeshadriR that second part you said does not appear to be true. I am able to iterate (if _ in range(5)) in non-interactive mode. With that said, in both situations dir() shows that the _ does not get saved like a "normal" variable would from a for loop, therefore yes I agree this answer is incorrect. – lobi Jun 26 '20 at 16:58
0

Your code

stamps = set()
for _ in range(int(raw_input())):
    print 'underscore is', _
    stamps.add(raw_input().strip())
    print stamps

is exactly equivalent to this:

how_many_loops = int(raw_input()) # asked only once.
stamps = set()
for i in range(how_many_loops):
    print 'loop count is', i
    stamps.add(raw_input().strip())
    print stamps

Because whatever you put in range() has to be calculated before the loop starts, so the first int(raw_input()) is asked only once. If you use something like for i in range(very_expensive_list) it will take a bunch of time then start the loop.

Guimoute
  • 2,676
  • 1
  • 7
  • 21