What is the purpose of the single underscore "_" variable in Python?
Question:
What is the meaning of _
after for
in this code?
if tbh.bag:
n = 0
for _ in tbh.bag.atom_set():
n += 1
Answers:
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.
_
has 3 main conventional uses in Python:
-
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
-
For translation lookup in i18n (see the
gettext
documentation for example), as in code like
raise forms.ValidationError(_("Please enter a correct username"))
-
As a general purpose "throwaway" variable name:
-
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(':')
-
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.
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()
There are 5 cases for using the underscore in Python.
-
For storing the value of last expression in interpreter.
-
For ignoring the specific values. (so-called “I don’t care”)
-
To give special meanings and functions to name of variables or functions.
-
To use as ‘internationalization (i18n)’ or ‘localization (l10n)’ functions.
-
To separate the digits of number literal value.
Here is a nice article with examples by mingrammer.
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).
What is the meaning of _
after for
in this code?
if tbh.bag:
n = 0
for _ in tbh.bag.atom_set():
n += 1
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.
_
has 3 main conventional uses in Python:
-
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 -
For translation lookup in i18n (see the
gettext
documentation for example), as in code likeraise forms.ValidationError(_("Please enter a correct username"))
-
As a general purpose "throwaway" variable name:
-
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(':')
-
As part of a function definition (using either
def
orlambda
), 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 ifday
is not used later in the code. The fix, ifday
is truly not needed, is to writeyear, 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 writelambda _: 1.0
. An unused variable is often hiding a bug/typo (e.g. setday
but usedya
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 explicitdel name
call will both satisfy linters that the name is being used, and promptly clear the reference to the object. -
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()
There are 5 cases for using the underscore in Python.
-
For storing the value of last expression in interpreter.
-
For ignoring the specific values. (so-called “I don’t care”)
-
To give special meanings and functions to name of variables or functions.
-
To use as ‘internationalization (i18n)’ or ‘localization (l10n)’ functions.
-
To separate the digits of number literal value.
Here is a nice article with examples by mingrammer.
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 amatch
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 thebuiltins
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 tobuiltins._
.>>> 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 tobuiltins._
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).