Factsheet
Whats the difference between (), [] and {}?
python - What's the difference between () vs [] vs {}? - Stack Overflow
python - What does ** (double star/asterisk) and * (star/asterisk) do for parameters? - Stack Overflow
What does asterisk * mean in Python? - Stack Overflow
Videos
I cant seem to understand the difference between them. I know [] is used for lists but thats it. If someone could explain them in detail to a newbie like me, id greatly appreciate it.
() - tuple
A tuple is a sequence of items that can't be changed (immutable).
[] - list
A list is a sequence of items that can be changed (mutable).
{} - dictionary or set
A dictionary is a list of key-value pairs, with unique keys (mutable). From Python 2.7/3.1, {} can also represent a set of unique values (mutable).
- () is a tuple: An immutable collection of values, usually (but not necessarily) of different types.
- [] is a list: A mutable collection of values, usually (but not necessarily) of the same type.
- {} is a dict: Use a dictionary for key value pairs.
For the difference between lists and tuples see here. See also:
- Python Tuples are Not Just Constant Lists
The *args and **kwargs are common idioms to allow an arbitrary number of arguments to functions, as described in the section more on defining functions in the Python tutorial.
The *args will give you all positional arguments as a tuple:
def foo(*args):
for a in args:
print(a)
foo(1)
# 1
foo(1, 2, 3)
# 1
# 2
# 3
The **kwargs will give you all
keyword arguments as a dictionary:
def bar(**kwargs):
for a in kwargs:
print(a, kwargs[a])
bar(name='one', age=27)
# name one
# age 27
Both idioms can be mixed with normal arguments to allow a set of fixed and some variable arguments:
def foo(kind, *args, bar=None, **kwargs):
print(kind, args, bar, kwargs)
foo(123, 'a', 'b', apple='red')
# 123 ('a', 'b') None {'apple': 'red'}
It is also possible to use this the other way around:
def foo(a, b, c):
print(a, b, c)
obj = {'b':10, 'c':'lee'}
foo(100, **obj)
# 100 10 lee
Another usage of the *l idiom is to unpack argument lists when calling a function.
def foo(bar, lee):
print(bar, lee)
baz = [1, 2]
foo(*baz)
# 1 2
In Python 3 it is possible to use *l on the left side of an assignment (Extended Iterable Unpacking), though it gives a list instead of a tuple in this context:
first, *rest = [1, 2, 3, 4]
# first = 1
# rest = [2, 3, 4]
Also Python 3 adds a new semantic (refer PEP 3102):
def func(arg1, arg2, arg3, *, kwarg1, kwarg2):
pass
Such function accepts only 3 positional arguments, and everything after * can only be passed as keyword arguments.
Note:
A Python dict, semantically used for keyword argument passing, is arbitrarily ordered. However, in Python 3.6+, keyword arguments are guaranteed to remember insertion order.
"The order of elements in **kwargs now corresponds to the order in which keyword arguments were passed to the function." - Whatβs New In Python 3.6.
In fact, all dicts in CPython 3.6 will remember insertion order as an implementation detail, and this becomes standard in Python 3.7.
It's also worth noting that you can use * and ** when calling functions as well. This is a shortcut that allows you to pass multiple arguments to a function directly using either a list/tuple or a dictionary. For example, if you have the following function:
def foo(x,y,z):
print("x=" + str(x))
print("y=" + str(y))
print("z=" + str(z))
You can do things like:
>>> mylist = [1,2,3]
>>> foo(*mylist)
x=1
y=2
z=3
>>> mydict = {'x':1,'y':2,'z':3}
>>> foo(**mydict)
x=1
y=2
z=3
>>> mytuple = (1, 2, 3)
>>> foo(*mytuple)
x=1
y=2
z=3
Note: The keys in mydict have to be named exactly like the parameters of function foo. Otherwise it will throw a TypeError:
>>> mydict = {'x':1,'y':2,'z':3,'badnews':9}
>>> foo(**mydict)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: foo() got an unexpected keyword argument 'badnews'
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'}