Python is a general-purpose programming language. It is an interpreted language, i.e. source code is not compiled into an executable file but it is directly executed by an interpreter. A file containing Python code can be executed like this:
python my_code.py
Python can also act as an interactive interpreter where you can type and run Python code line-by-line. It can be started by simply running
python
You have the full power of Python in there, but it is not very convenient. A much better alternative is IPython, which is described on a separate page.
Actually, this very page you're just reading is a so-called IPython notebook, which means that you can view it either as a static web page or, if you have IPython installed locally, you can also open the notebook file with IPython and run the code in it interactively. You can also change stuff and play around with it. To execute a code cell, select it by clicking on it and press Shift+Enter. You can step through all the cells by pressing Shift+Enter repeatedly.
TODO
Bottom line: use Python 3!
The appropriate commands may be called python3
and ipython3
on your computer.
The programming language Python is named after the famous British comedy group Monty Python. If that doesn't ring a bell, you should search the interwebs and watch some videos of them, they are hilarious! In Python example code, you will often find references to their sketches, e.g. a list may contain ["eggs", "bacon", "spam"]
which would be a reference to Monty Python's Spam Sketch.
According to international law, every programming language tutorial has to start by showing how to print the sentence "Hello, world!" to the screen. This is how it's done in Python:
print("Hello, world!")
Hello, world!
Here you can see how a function is called (more precisely, a built-in function named print
) with one argument. Furthermore, you see how string literals are created.
It's pretty simple.
But now for something completely different:
Everybody loves numbers, right? In Python, there are two types of numbers. On the one hand, there are integers like
42
42
... and on the other hand, there are floating point numbers like
3.1415
3.1415
You probably know that "everything in Python is an object", which is also true for numbers. Numbers are objects. And every object has a type, so let's check that:
type(42)
int
Looks close enough to "integer", doesn't it?
type(3.1415)
float
... and this is supposed to mean "floating point number".
If you want to convert an int
to a float
, you can do it like this:
float(42)
42.0
TODO: infinite precision int
(or long
?), double precision float
TODO: more numeric types in external libraries, e.g. NumPy
To be completely honest, there is a third type of numbers built into the core of the Python language: complex numbers.
2.4 + 3.1j
(2.4+3.1j)
Appending a lower-case j
to a number (without a space in-between), makes it an imaginary number.
Let's look at the type of the whole thing:
type(2.4 + 3.1j)
complex
A complex
is basically a pair of float
s, one for the real part and one for the imaginary part. Complex numbers can come in very handy when doing scientific computations.
You can find more information about Python's numeric types in the official documentation.
Numbers are great. Let's see how they interact with each other.
2 + 3
5
2.0 + 3.0
5.0
5 + 2.5
7.5
2 * 3
6
-4 * (3 + 1) - 0.5
-16.5
5 / 2
2.5
So far, not really surprising results. You can mix int
s and float
s. As soon as a float
is involved, the result is also a float
.
Attention: integer division behaves differently in Python 2 and Python 3!
In Python 2, it behaved like in the programming language C, i.e. the result was truncated to an integer, e.g. 5 / 2
would return 2
and the result would be of type int
.
In Python 3, however, the behavior was changed and now even the division of two int
s returns a float
.
If you want the old truncating behavior of Python 2, you can use the //
operator:
5 // 2
2
On the other hand, if you want the new behaviour in Python 2, just write this line before your calculations (in the beginning of your script):
from __future__ import division
Alternatively, you can of course also just convert one of the operands (or both) to float
beforehand.
Let's see, what else do we have?
Powers, for example. While you might be used to the ^
operator from other languages, Python uses **
for that. The ^
operator is a very different thing, namely logical xor. Don't confuse the two!
3 ** 2
9
Of course, there is also a modulo operator:
13 % 4
1
Besides the these arithmetic operators, there are also comparison operators which return boolean values.
3 > 4
False
3 <= 4
True
3 + 1 == 4
True
As we saw above, strings can be written using double quotes:
"Hello, world!"
'Hello, world!'
However, it's also possible to write them with single quotes:
'Hello, world!'
'Hello, world!'
To the Python interpreter, this doesn't make a difference. It is, however, common to use double quotes for strings containing natural language and anything that is at some point presented to the user. Single quotes are normally used for short strings which only appear inside a program.
Both variants have the type str
:
type("Hello, world!")
str
You can use str()
to convert any object to a string:
str(42)
'42'
There is a special notation for writing multi-line string literals using triple double quotes:
"""One,
two,
three lines"""
'One,\ntwo,\nthree lines'
The same can also be written with triple single quotes, but this is much less common.
Strings can be concatenated with the +
operator:
"Hello" + "," + " " + "world" + "!"
'Hello, world!'
The *
operator (in combination with an int
) has a special meaning for a str
:
"#" * 79
'###############################################################################'
Unlike in many other programming languages, there is no separate type for single characters in Python. Single characters are simply written as strings which happen to contain only one character.
Each character has a numeric equivalent which can be shown by the ord()
function.
The function chr()
can be used to convert in the other direction.
ord(" ")
32
chr(65)
'A'
If you want to create a string that contains formatted numeric values, it's best to use the format()
method:
"The value of {} is about {:.3}".format("𝜋", 3.1415)
'The value of 𝜋 is about 3.14'
Here you can also see that Python supports Unicode characters by default.
In older Python code you might find a different way of string formatting:
"The value of %s is about %.2f" % ("𝜋", 3.1415)
'The value of 𝜋 is about 3.14'
This old-style string formatting is quite similar to the above, but sometimes less flexible and more error-prone.
In case of doubt, you should use the more modern format()
method.
There is much more to say about strings. To learn more about them, have a look at the official str
documentation.
A list
is a container that can hold arbitrary objects. A list
can be created by putting objects, separated by commas, between a pair of brackets.
[42, 3.1415, "Ni!"]
[42, 3.1415, 'Ni!']
Note that a list
doesn't contain the actual objects, it just contains references to the objects.
An empty list looks like this:
[]
[]
Of course, a list can also have just a single element:
[7]
[7]
To concatenate multiple lists, the +
operator can be used:
[1, 2] + [3] + [4, 5, 6]
[1, 2, 3, 4, 5, 6]
Similar to strings, you can also use the *
operator (in combination with an int
) to repeat lists:
[1, 2, 3] * 5
[1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]
Like everything else, lists are also objects, and they have a type:
type([1, 2, 3])
list
We can use list()
to create a list from some other object (which must be iterable):
list("Hello, world!")
['H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '!']
It's very easy to create a list of strings from a single space-separated string:
"eggs bacon spam".split()
['eggs', 'bacon', 'spam']
Of course, there are options available to change the separator.
To combine a sequence of strings into a single string, use the join()
method (applied to the "glue" string):
" + ".join(["eggs", "bacon", "spam"])
'eggs + bacon + spam'
Lists are mutable data structures, i.e. their elements can be changed. But more about that later ...
Tuples are quite similar to list
s, with the main difference that they are immutable data structures, i.e. their content cannot be changed. Some objects, separated by commas, create a tuple:
42, 3.1415, "Ni!"
(42, 3.1415, 'Ni!')
Just like lists, tuples can also hold arbitrary objects (and they contain references, not the actual objects).
Tuples are often enclosed in parentheses, but those are only really required if otherwise the code would be ambiguous, e.g. when creating a tuple of tuples:
1, (2, 3), 4
(1, (2, 3), 4)
Another situation where parentheses are obligatory, are empty tuples:
()
()
Attention: Putting a single item between parentheses does not create a tuple!
(7)
7
This is because parentheses can be used around arbitrary expressions to force operator precedence.
This has nothing to do with tuple
s:
(6 + 1) * 6
42
A non-empty tuple is created with an obligatory comma, the parentheses are optional:
7,
(7,)
Like str
and list
, tuple
s can be concatenated with the +
operator and repeated with *
:
(1, 2) + (3,) * 5
(1, 2, 3, 3, 3, 3, 3)
Note that the parentheses are obligatory in this case.
It should come as no surprise that tuples also have a type:
type((1, 2, 3))
tuple
Note that when used as a function argument, the tuple has to be enclosed in parentheses (otherwise it would be interpreted as a function call with multiple arguments).
When you write Python code, you write a sequence of statements. There are several different kinds of statements, some of which will be explained in this notebook.
What we were seeing up to now were expression statements. Each of the code cells above holds an expression. Simply put, an expression is a piece of code that can be evaluated which results in some value, or more generally speaking, some object.
An expression may contain arbitrarily many other expressions, but no statements.
A statement, however, may contain expressions and sometimes also other statements.
An expression always returns a value, a statement never returns a value.
But never say never ...
There is this strange thing called expression statement, which turns an expression into a statement by ignoring its return value. But when used in an interactive Python session, this behaves differently! When evaluating a statement which happens to be an expression, on an interactive Python prompt, the result will actually be shown to you. In an IPython notebook, a code cell may contain multiple statements, and if the last one happens to be an expression statement, its value is returned:
[2 + 2, 4 + 4, 6 + 6]
10 * 9 + 9
"Hello, World!"
4 < 3
7 * 6
42
As you see, there are several expressions in the code cell above; all of them are evaluated, but only the result of the last one is shown.
So what's the use of those expressions above if we don't see their results?
There is none.
Unless they have side effects ...
Some expressions not only return a value, they also do some other things which don't have anything to do with returning values. Those other things are called side effects. For more information see the Wikipedia article.
For, example, the print()
function which we saw at the very top of this page, prints the given arguments to the standard output.
print("Hello, world!")
7 * 6
Hello, world!
42
The string "Hello, world!"
which is printed by the print()
function, is not the return value of the function!
What we see here is the so-called standard output which, in an IPython notebook, is displayed just below the code cell, but above the actual output values (marked by Out[...]:
).
The actual return value is the result of the last expression in the code cell.
So what's the return value of the print()
function?
A function call is just an expression, so it should have a return value, right?
Let's check:
print("Hello, world!")
Hello, world!
As you can see, there is no Out[...]:
section above.
Does this mean that the line isn't an expression?
Or does this mean that, contrary to what I told you, not all expressions return a value?
No, I didn't lie to you!
By convention, when a Python expression doesn't have anything meaningful to return (like the print()
function), it returns a special Python object called None
.
This is Python's way of saying "nothing".
You see, even "nothing" is an object in Python!
So this function returns None
, but the interactive interpreter, again by convention, doesn't show this, since it's just "nothing", anyway.
Let's check:
None
Really, we see nothing.
We can use the is
-operator to check if some object is None
(see below for an explanation of the is
-operator).
print("Hello, world!") is None
Hello, world!
True
Now we can see that the print()
function prints its argument to the standard output and returns None
.
Very often, one line of code is one statement, but sometimes statements can also span several lines. And we can fit multiple statements into one line by separating them with semicolons:
print("semicolons are rare in Python code"); 2 + 2
semicolons are rare in Python code
4
Most of the time, however, this is not necessary. Others will understand your code better if you start each statement on a new line.
Another use of the semicolon, in an interactive Python session, is to ignore the value of the last expression (the ones before are ignored anyway):
7 * 6
3.1415
2 + 2;
In a "normal" Python program this is never necessary, because the return value of expressions in expression statements is always ignored.
You will need this very rarely, don't make it a habit to end your lines with semicolons!
Until now, we talked about expression statements. There are several other kinds of statements which can be used to control program flow, define functions and classes, raise exceptions etc.
Let's continue with a very important statement: the assignment statement.
Assignment may seem to be a trivial topic, but there are some subtleties involved. So please bear with me, since this is essential stuff.
Note that assignment is a statement and not an operator. An assignment cannot be used as part of an expression. This may be surprising if you're used to programming in C or similar programming languages. If not, it might seem quite straightforward, though.
An assignment statement consists of three things:
=
, not to be confused with the above-mentioned equality operator ==
),The part to the right is easy, this can be just any expression, e.g. any of the expressions from above could be on the right side of an assignment.
The "something on the left" is the more interesting part. This can be one of several quite different things, which are described in the following sections. For all the gory details, have a look in the official Python documentation.
The "something on the left" can be a so-called identifier. This is a name that can be bound to an object. An identifier may only contain letters, numbers and underscores and it must not start with a number.
answer = 7 * 6
In this example, the expression to the right of the equals sign is evaluated, creating a new object (of type int
) with the value 42
.
The assignment statement binds the identifier answer
to this new object.
Note that the identifier answer
didn't exist before.
In Python, it's not necessary to declare identifiers, new identifiers are created by just assigning to them.
Once a name has been assigned, it can be used in an expression, as a reference to the original object:
answer > 50
False
Some Python beginners use the wrong mental image when thinking of Python variables/identifiers. In some other programming languages, a variable can be thought of "a box where we can store a certain type of value in". Over the course of a program, we can put different values into this box. For example, in the programming language C it might look something like this:
int answer;
answer = 7 * 6;
In this code snippet, a variable named answer
is first declared.
At this point, the type of the variable has to be specified.
Later, a value (of the correct type) is assigned to the variable.
Note: This is actually bad style. You should never declare an uninitialized variable, because if you forget to assign a value to it, this might lead to very strange and hard-to-find errors. In this example, it would be better to do the declaration and initialization in one statement:
int answer = 7 * 6;Anyway, this isn't a C tutorial ...
In this C-example, the variable named answer
is actually a "box where we can store an int
value".
And later, if we feel like it, we can put another value into the box, which overwrites (and therefore destroys) the old value.
In Python, this is different.
The identifier named answer
is not a "box".
It is rather a "label", similar to a sticky note which we can stick onto an (already existing) object.
In our example, we stick it to an object that has the type int
and the value 42
.
This object was created by the Python interpreter during evaluation of the expression 7 * 6
.
The object itself doesn't have a name (it just has a memory address), but we can bind a name to it, in our example the name answer
.
Now what happens in the following statement?
type(answer)
int
It looks like the identifier answer
has a type after all!
But strictly speaking, this isn't true.
An identifier is one of the few things in Python that isn't an object.
Therefore, it doesn't have a type, either.
However, an identifier is always bound to an object.
In other words, an identifier is a reference to an object.
Whenever we use an identifier, it is as if we were using the actual referenced object instead.
This is why the previous statement returned int
, which isn't the type of the identifier but the type of the object it's bound to.
The only place where an identifier is not treated like the object it's bound to, is on the left side of an assignment statement. That's also the reason why assignment is not (and cannot be) an operator and why it cannot be used as part of an expression.
We learned that a new identifier can be created by just using a name that hasn't been used before in an assignment statement.
But what happens if we assign to a name that has already been used?
answer = "Sir Lancelot of Camelot"
Well, nothing special.
The name answer
is just re-bound to the object at the right side of the equals sign.
Here we also see that the identifier itself doesn't have a type, it's just a label that is bound to some object.
The objects themselves do have types; the previous one was of type int
while the new one is of type str
.
type(answer)
str
So what happened to the int
object with the value 42
?
It's not overwritten, but we cannot access it anymore, because we don't have an identifier that references it. Have a look at Garbage Collection below to see what the Python interpreter does with objects which are not bound to any name.
Note that an identifier is only treated specially on the left side of an assignment statement. The right side of the assignment statement is just a normal expression which can contain other identifiers (or even the same identifier that is going to be re-bound on the left).
greeting = answer + ", nice to meet you!"
greeting = "My name is " + greeting
Since assignment is a statement which doesn't return a value, we don't see the value of the new object where greeting
is bound to.
Let's have a look:
greeting
'My name is Sir Lancelot of Camelot, nice to meet you!'
Of course, one object can have multiple labels stuck to it:
the_same_greeting = greeting
the_same_greeting
'My name is Sir Lancelot of Camelot, nice to meet you!'
Obviously, the returned string has exactly the same characters.
In other words, it's equal to greeting
.
We can check this with the equality operator:
greeting == the_same_greeting
True
But the two are more than equal!
They are actually two different names for the same object.
To show that, we can check Python's internal representation of the objects.
Each object that's currently existing in the Python interpreter, has a unique ID, which we can query with the id()
function:
id(greeting)
140480868235344
id(the_same_greeting)
140480868235344
As we can see, the two objects have the same ID, so it's actually just one object that happens to have two names bound to it.
Python even has a special operator for checking if two objects are actually the same object: the identity operator.
greeting is the_same_greeting
True
We normally don't care about the actual IDs, if we want to see if two objects are identical (which is not the same as equal!), we use the is
-operator.
If you want to bind several names to the same object in one go, you can use a special form of the assignment statement that uses multiple equals signs:
one = two = three = "data"
Now all of the identifiers one
, two
and three
are bound to the same str
object.
You may not need that very often, but it's still good to know.
Let me emphasize again: An identifier in Python isn't a box where we can put values into, it's rather a label that we attach to an existing object.
Many Python tutorials make the mistake of explaining Python variables (which should probably better be called identifiers) as "boxes", but that's plain wrong.
The error can easily be shown by creating multiple identifiers which are bound to the same object.
Let's use the previous example:
If one
, two
and three
would actually be "boxes", each one of them would have to hold its own copy of the string "data"
.
Therefore, each of the three strings would have to be a different str
object.
But we can easily show that the three identifiers are bound to the same one and only one object:
one is two is three
True
Another misconception that comes with the "box"-analogy, is that an assignment puts the new data at the same memory location where the old data was before, effectively overwriting the old object.
This is far from true. When assigning to an already existing identifier, we do not change any object, we just stick the label onto a different object. The new object must already exist before it is bound to the identifier, therefore it has to occupy a different memory area than the old object. The old object may or may not be destroyed right after the assignment, but that's a very different story (see Garbage Collection).
It can be easily shown that assignment doesn't overwrite old data:
number = 0
id(number)
10383456
number = 1
id(number)
10383488
If the second assignment would overwrite the memory area of the old data, id()
would return the same value as before.
But we see that the IDs are different, therefore, 0
and 1
must be different objects.
I'm sorry that I have to repeat my self so often, but this is really important: Assignment to an existing identifier does not modify any object!
We'll see a bit further down how we can actually modify objects.
I try to avoid using the term "variable" for a Python identifier, because I think many people will associate this term with a "box", rather than a "label". But it's of course not forbidden to call it variable, and sometimes it just sounds more natural.
By the way, if you want to use more technical terms instead of "box" and "label", you can use the terms value semantics and reference semantics, respectively. Python has reference semantics.
Binding a name to an object is nothing special; nearly every programming language can do that in one form or another.
But Python has a very nice additional feature that not many other languages have, that allows to bind multiple identifiers to a sequence of objects in a single statement. Some people also call this tuple unpacking or sequence unpacking.
a, b, c = 42, 3.1415, "Ni!"
This can also be used to easily swap things (again, in a single statement):
b, c = c, b
b
'Ni!'
On the right side, there can be any iterable object. We already know a few iterable things: a tuple, a list, a string; but there are many more iterable objects out there, just waiting to be discovered!
On the left side, there are several identifiers, separated by commas. They can optionally be enclosed in parentheses or brackes. The number of identifiers must be the same as items in the iterable object on the right. If not, an error is raised.
But there is an exception: one of the identifiers may be prefixed with an asterisk, which means that the identifier receives a list of the remaining values, regardless how many they are (the list can also be empty). Maybe this is best shown in an example:
first, *middle, last = "hello"
middle
['e', 'l', 'l']
That's great, isn't it? By the way, this is sometimes called extended unpacking.
Note, however, that the thing with the starred identifier is only available in Python 3.
In this example you can see that a string can also be unpacked, since it is iterable.
The list of identifiers doesn't have to be a flat list, it can be arbitrarily nested (using parentheses and/or brackets). It doesn't even have to be limited to "plain" identifiers, it can also contain any of the things mentioned below (attribute references, subscripts, slices).
It has been quite a while, but I'm still speaking about different variants of the assignment statement. Until now, we just moved labels around, but this one is the first one where we can actually change objects.
Every object has attributes.
They can be accessed by placing a dot (.
) and the identifier of the attribute after the object.
If an attribute reference is the "something on the left" of the equals sign in an assignment statement, it is bound to the object on the right of the equals sign. If an attribute with the given name doesn't yet exist, it is created.
Note, however, that not all objects allow attribute assignment and even if they do, only a few special attributes may be allowed to assign to.
It is especially hard to find objects that allow attribute assignment within the built-in types we've seen so far. We didn't learn yet how to import stuff from the standard library nor from external libraries; we didn't learn how to create our own classes. Without explaining any of this, I couldn't find an example that shows attribute assignment. Bad luck. But I guess you'll understand it anyway, even without an example.
Another thing on the left of the equals sign in an assignment statement can be an object followed by a pair of brackets with some expression inside.
This is normally available for some kind of collection, like for example a list
.
mylist = ["one", "two", "five"]
In case of a list
, the subscript (the expression inside of the brackets) must be a single integer.
Note that Python, like many other programming languages, starts indexing at 0
(which is the only reasonable choice for a programming language).
So if we want to address the third element of a list, we have to use the subscript 2
:
mylist[2] = "three"
Again, since this is a statement, no value is returned.
mylist
['one', 'two', 'three']
Note that when assinging to a list element, as always, the value is not copied, but merely a reference inside of the list is bound to the object on the right of the equals sign.
To show this, we can assign a single object to multiple list elements:
mylist[0] = mylist[2]
The thing on the left of the equals sign is again treated specially (because the specified list element is bound to another object).
The thing on the right side of the equals sign is just a normal expression, consisting of an identifier with the subscript operator.
This expression get's evaluated which results in the object which is stored as the third element of the list mylist
(the string "three"
).
Strictly speaking, the object is not stored inside of the list, the list holds just a reference to this object.
This assignment statement binds the reference at the first list element to the very same object. It may seem as if there are two copies of the string stored in the list ...
mylist
['three', 'two', 'three']
... but the is
-operator tells us that those are just references to a single object:
mylist[0] is mylist[2]
True
Negative subscripts are also allowed, which let us index a sequence from the end to the beginning.
The last element corresponds to the index -1
.
mylist[-1] = 'one'
mylist
['three', 'two', 'one']
Note that assignment to elements of a tuple
or to characters of a str
is not possible, since both types are immutable!
However, there are many other mutable types which allow subscription assignment.
Depending on the type, the subscript operator may not (only) accept int
values but (also) str
or tuple
or ...
One example for such a type is dict
, which will be explained further down (see Dictionaries).
Slicing is just a special case of numeric subscription. Instead of a single number, a range of numbers (a so-called slice) is specified.
First, let's re-bind the identifier we used before.
mylist = ["one", "two", "three", "four", "five"]
Instead of specifying a single integer as subscript, we use a colon to specify a range of indices.
mylist[1:4] = 2, 3, 4
mylist
['one', 2, 3, 4, 'five']
As mentioned before, Python starts indexing at 0
.
The stop
value of the slice is also "special", since the slice indices go up to, but not including, the stop
value.
In other words, the subscript in mylist[start:stop]
describes the half-open interval [start
, stop
).
This may take some time to get used to, but in the long run you'll see that this is a much more straightforward choice then including the stop
value in the slice.
For more details about this concept, see Why numbering should start at zero from E. W. Dijkstra.
The start
and stop
values are optional.
If omitted, the slice starts at the beginning of the sequence or reaches until the end, respectively.
mylist[:3] = "123"
mylist
['1', '2', '3', 4, 'five']
mylist[3:] = "IV", "V", "VI"
mylist
['1', '2', '3', 'IV', 'V', 'VI']
As you see here, the number of elements on the left of the equals sign doesn't have to be the same as on the right (except when you use a step size other than one, see below).
To replace the whole list contents, a single colon (without start
and stop
) can be used.
mylist[:] = 0, 1, 2, 3, 4, 5, 6, 7
mylist
[0, 1, 2, 3, 4, 5, 6, 7]
Note that in this case, the actual list
object is mutated, whereas if an identifier is merely re-bound (mylist = ...
), the original list
object is not mutated.
In addition to start
and stop
, a slice object can also have a step
size (specified after a second colon).
mylist[3::2] = "357"
mylist
[0, 1, 2, '3', 4, '5', 6, '7']
The default step
size is, not surprisingly, 1
.
Like start
and stop
, the step
size can also be negative, meaning a reversed order from the end to the beginning:
mylist[::-2] = "seven", "five", "three", "one"
mylist
[0, 'one', 2, 'three', 4, 'five', 6, 'seven']
Note that the colon-operator is only allowed within the brackets of a subscript.
If you want to create a slice object at a different place, you have to use slice()
.
slice(4)
slice(None, 4, None)
If one of start
, stop
, step
is not specified, it is set to None
.
Like in the colon-notation, each of them is optional.
slice(None)
slice(None, None, None)
slice(1, 4)
slice(1, 4, None)
slice(1, None, 2)
slice(1, None, 2)
TODO: mutable vs. immutable
# docstrings
# built-in functions
TODO: logic (boolean) operators, in, not in, bit-wise operators
if
Statements¶if
/else
expressionslambda
s)*args
, **kwargs