812

What is the meaning of _ after for in this code?

if tbh.bag: n = 0 for _ in tbh.bag.atom_set(): n += 1 
0

6 Answers 6

1030

_ has 3 main conventional uses in Python:

  1. To hold the result of the last executed expression in an interactive interpreter session (see docs). This precedent was set by the standard CPython interpreter, and other interpreters have followed suit

  2. For translation lookup in i18n (see the gettext documentation for example), as in code like

    raise forms.ValidationError(_("Please enter a correct username")) 
  3. As a general purpose "throwaway" variable name:

    1. To indicate that part of a function result is being deliberately ignored (Conceptually, it is being discarded.), as in code like:

      label, has_label, _ = text.partition(':') 
    2. As part of a function definition (using either def or lambda), where the signature is fixed (e.g. by a callback or parent class API), but this particular function implementation doesn't need all of the parameters, as in code like:

      def callback(_): return True 

      [For a long time this answer didn't list this use case, but it came up often enough, as noted here, to be worth listing explicitly.]

    This use case can conflict with the translation lookup use case, so it is necessary to avoid using _ as a throwaway variable in any code block that also uses it for i18n translation (many folks prefer a double-underscore, __, as their throwaway variable for exactly this reason).

    Linters often recognize this use case. For example year, month, day = date() will raise a lint warning if day is not used later in the code. The fix, if day is truly not needed, is to write year, month, _ = date(). Same with lambda functions, lambda arg: 1.0 creates a function requiring one argument but not using it, which will be caught by lint. The fix is to write lambda _: 1.0. An unused variable is often hiding a bug/typo (e.g. set day but use dya in the next line).

    The pattern matching feature added in Python 3.10 elevated this usage from "convention" to "language syntax" where match statements are concerned: in match cases, _ is a wildcard pattern, and the runtime doesn't even bind a value to the symbol in that case.

    For other use cases, remember that _ is still a valid variable name, and hence will still keep objects alive. In cases where this is undesirable (e.g. to release memory or external resources) an explicit del name call will both satisfy linters that the name is being used, and promptly clear the reference to the object.

Sign up to request clarification or add additional context in comments.

28 Comments

Could you explain how it works in a function call, for example: raise forms.ValidationError(_("Please enter a correct username")). I've seen this in Django code, and it's not clear what's going on.
That is usage 2 - by convention, _ is the name used for the function that does internationalisation and localisation string translation lookups. I'm pretty sure it is the C gettext library that established that convention.
FWIW, I've personally started using __ (a double underscore) as my general purpose throwaway variable to avoid conflicting with either of the first two use cases.
Emergent community conventions don't tend to have authoritative sources - just observations of the practices that have appeared over time. FWIW, I'm one of the co-authors of more recent PEP 8 updates, and my answer is based on the 3 different ways I've seen _ used as a variable name since I started using Python professionally in 2002.
The convention is mainly for tuple unpacking: a, __, c = iterable tells the reader immediately that we're unpacking a 3-tuple, but only using the first and last values. If we instead write a, b, c = iterable, the reader (or an automated code linter) can reasonably expect all of a, b, and c to be used later (and if they're not, it may be a sign of a bug somewhere).
|
261

It's just a variable name, and it's conventional in python to use _ for throwaway variables. It just indicates that the loop variable isn't actually used.

7 Comments

you mean it doesn't represent the last returned value?
@steve only in a python shell
similar to the use of _ in Prolog
similar to the use of ~ in Matlab
Note that in the cpython shell if you explicitly define _, it permanently stops holding the output value of the previous expression. This seems horribly inconsistent, and the Python lang standards need to address this. They should just define _ to be a throwaway name and stop it from being used as a real identifier.
|
138

Underscore _ is considered as "I don't care" or "throwaway" variable in Python

  • The python interpreter stores the last expression value to the special variable called _.

    >>> 10 10 >>> _ 10 >>> _ * 3 30 
  • The underscore _ is also used for ignoring the specific values. If you don’t need the specific values or the values are not used, just assign the values to underscore.

    Ignore a value when unpacking

    x, _, y = (1, 2, 3) >>> x 1 >>> y 3 

    Ignore the index

    for _ in range(10): do_something() 

7 Comments

There's a third usage, which is for the internationalization function _("Hello world!").
At the processor level, is there actually difference between "for _ in range" and "for x in range" and then not using x? Or is it just for human readability?
@iammax Using the dis module I found there was no difference in the bytecode. The benefits of human readability are obvious, however.
@ado What do you mean? What are you printing, and what are you expecting to see exactly? If you do >>> 10 then >>> print(_), 10 will be printed, if that's what you mean.
@adosar Ah, I see! I suppose it's because None isn't worth remembering, that is, it's not important, the same reason it isn't printed after running print(). I could go on if you want more reasoning. This behaviour is also documented under sys.displayhook (the mechanism that prints evaluated output): "If value is not None, this function prints repr(value) to sys.stdout, and saves value in builtins._."
|
33

There are 5 cases for using the underscore in Python.

  1. For storing the value of last expression in interpreter.

  2. For ignoring the specific values. (so-called “I don’t care”)

  3. To give special meanings and functions to name of variables or functions.

  4. To use as ‘internationalization (i18n)’ or ‘localization (l10n)’ functions.

  5. To separate the digits of number literal value.

Here is a nice article with examples by mingrammer.

2 Comments

Numbers 3 and 5 don't really apply to this question. OP's asking about a single underscore as a standalone name, but point 3 talks about using underscores as part of a bigger name, and point 5 talks about using it in a literal, not a name. I'm just mentioning in case any newbies are confused. It might help to edit the answer to clarify it.
20

As far as the Python languages is concerned, _ generally has no special meaning. It is a valid identifier just like _foo, foo_ or _f_o_o_.
The only exception are match statements since Python 3.10:

In a case pattern within a match statement, _ is a soft keyword that denotes a wildcard. source

Otherwise, any special meaning of _ is purely by convention. Several cases are common:

  • A dummy name when a variable is not intended to be used, but a name is required by syntax/semantics.

    # iteration disregarding content sum(1 for _ in some_iterable) # unpacking disregarding specific elements head, *_ = values # function disregarding its argument def callback(_): return True 
  • Many REPLs/shells store the result of the last top-level expression to builtins._.

    The special identifier _ is used in the interactive interpreter to store the result of the last evaluation; it is stored in the builtins module. When not in interactive mode, _ has no special meaning and is not defined. [source]

    Due to the way names are looked up, unless shadowed by a global or local _ definition the bare _ refers to builtins._ .

    >>> 42 42 >>> f'the last answer is {_}' 'the last answer is 42' >>> _ 'the last answer is 42' >>> _ = 4 # shadow ``builtins._`` with global ``_`` >>> 23 23 >>> _ 4 

    Note: Some shells such as ipython do not assign to builtins._ but special-case _.

  • In the context internationalization and localization, _ is used as an alias for the primary translation function.

    gettext.gettext(message)

    Return the localized translation of message, based on the current global domain, language, and locale directory. This function is usually aliased as _() in the local namespace (see examples below).

Comments

-1

One more use of _ i came across recently is wildcard to handle unmatched values in match-case statement for example:

def check_number(x): match x: case 10: print("It's 10") case 20: print("It's 20") case _: print("It's neither 10 nor 20") check_number(10) check_number(30) 

Output :

It's 10 It's neither 10 nor 20 

This works even when _ is not initialized.

Also if you are working with interactive shell in python _ will hold result of last command.

Another strange behaviour which i noticed is when we use _ in python files without initialization it will result in error

>>> python -c "print(_)" Traceback (most recent call last): File "<string>", line 1, in <module> print(_) ^ NameError: name '_' is not defined 

but if you run same code in Jupyter notebook it will result in a empty string

print(type(_), repr(_)) <class 'str'> '' 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.