for i in range(10):
print('Hello!')Can we refer to in as a membership operator here?
print('a' in 'apple')What exactly is "in"? A keyword, operator, or something else.
while True:
studRegistered = int(input("Are you registering for Python 101? (Maximum 21 students): "))
if 1 <= studRegistered <= 21:
print(f"Successfully registered {studRegistered} student!")
break #once input was received
else:
print("Students registered must be between 1 and 21. Please re-enter: ")
Can you explain this scenario. I don't understand why range is written from 1<= studRegistered <21
Why can't (1,21) be used to validate the input? I'm not familiar with that operator.
Factsheet
_ 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
deforlambda), 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 ifdayis not used later in the code. The fix, ifdayis truly not needed, is to writeyear, month, _ = date(). Same with lambda functions,lambda arg: 1.0creates 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. setdaybut usedyain the next line).The pattern matching feature added in Python 3.10 elevated this usage from "convention" to "language syntax" where
matchstatements 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 namecall will both satisfy linters that the name is being used, and promptly clear the reference to the object.
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.
See Function Definitions in the Language Reference.
If the form
*identifieris present, it is initialized to a tuple receiving any excess positional parameters, defaulting to the empty tuple. If the form**identifieris present, it is initialized to a new dictionary receiving any excess keyword arguments, defaulting to a new empty dictionary.
Also, see Function Calls.
Assuming that one knows what positional and keyword arguments are, here are some examples:
Example 1:
# Excess keyword argument (python 3) example:
def foo(a, b, c, **args):
print("a = %s" % (a,))
print("b = %s" % (b,))
print("c = %s" % (c,))
print(args)
foo(a="testa", d="excess", c="testc", b="testb", k="another_excess")
As you can see in the above example, we only have parameters a, b, c in the signature of the foo function. Since d and k are not present, they are put into the args dictionary. The output of the program is:
a = testa
b = testb
c = testc
{'k': 'another_excess', 'd': 'excess'}
Example 2:
# Excess positional argument (python 3) example:
def foo(a, b, c, *args):
print("a = %s" % (a,))
print("b = %s" % (b,))
print("c = %s" % (c,))
print(args)
foo("testa", "testb", "testc", "excess", "another_excess")
Here, since we're testing positional arguments, the excess ones have to be on the end, and *args packs them into a tuple, so the output of this program is:
a = testa
b = testb
c = testc
('excess', 'another_excess')
You can also unpack a dictionary or a tuple into arguments of a function:
def foo(a,b,c,**args):
print("a=%s" % (a,))
print("b=%s" % (b,))
print("c=%s" % (c,))
print("args=%s" % (args,))
argdict = dict(a="testa", b="testb", c="testc", excessarg="string")
foo(**argdict)
Prints:
a=testa
b=testb
c=testc
args={'excessarg': 'string'}
And
def foo(a,b,c,*args):
print("a=%s" % (a,))
print("b=%s" % (b,))
print("c=%s" % (c,))
print("args=%s" % (args,))
argtuple = ("testa","testb","testc","excess")
foo(*argtuple)
Prints:
a=testa
b=testb
c=testc
args=('excess',)
I only have one thing to add that wasn't clear from the other answers (for completeness's sake).
You may also use the stars when calling the function. For example, say you have code like this:
>>> def foo(*args):
... print(args)
...
>>> l = [1,2,3,4,5]
You can pass the list l into foo like so...
>>> foo(*l)
(1, 2, 3, 4, 5)
You can do the same for dictionaries...
>>> def foo(**argd):
... print(argd)
...
>>> d = {'a' : 'b', 'c' : 'd'}
>>> foo(**d)
{'a': 'b', 'c': 'd'}
** in argument lists has a special meaning, as covered in section 4.7 of the tutorial. The dictionary (or dictionary-like) object passed with **kwargs is expanded into keyword arguments to the callable, much like *args is expanded into separate positional arguments.
The ** turns the dictionary into keyword parameters:
>>> d1 = {'a': 1, 'b': 2}
>>> d2 = {'c': 3, 'd': 4}
>>> d3 = dict(d1, **d2)
Becomes:
>>> d3 = dict(d1, c=3, d=4)
Have you ever been curious about the several meanings of underscores in Python? A little break-down?
- you can find detailed explanations and code snippets here
1️⃣ single leading underscore ("_var"): indicates that the variable is meant for internal use. This is not enforced by the interpreter and is rather a hint to the programmer.
2️⃣ single trailing underscore ("var_"): it's used to avoid conflicts with Python reserved keywords ("class_", "def_", etc.)
3️⃣ double leading underscores ("__var"): Triggers name mangling when used in a class context and is enforced by the Python interpreter.
What this means is that it should be used to avoid your method is being overridden by a subclass or accessed accidentally.
4️⃣ double leading and trailing underscores ("__var__"): used for special methods defined in the Python language (ex. __init__, __len__, __call__, etc.). They should be avoided to use for your own attributes.
5️⃣ single underscore ("_"): Generally used as a temporary or unused variable. (If you don't use the running index of a for-loop, you can replace it with "_").