There are built-in functions and the developers can of course define other functions. To call a function:
print("hello")
hello
Some functions return a result.
round(1.2)
1
It's common to store the result in a variable:
my_var = round(1.2)
which can then be used:
print(my_var)
1
int
, float
, bool
, complex
)str
list
tuple
int
(integers)¶a = 4
c = -10
# binary notation (base 2)
b = 0b010
# octal notation (base 8)
o = 0o011
# hexadecimal (base 16)
h = 0x1CF0
a = int("1") # base 10
a = int("111", 2) # base 2
a = int("70", 8) # base 8
a = int("16", 16) # base 16
Remark: int
in Python 3 are impressive! No limit!
print(10 + 3)
print(10 - 3)
print(10 * 3)
print(10 / 3) # float division
print(10 // 3) # integer division
print(10 % 3)
13 7 30 3.3333333333333335 3 1
bool
(booleans)¶b = bool("1")
b = False
b = True
==
equal!=
différent<
inferior<=
inferior or equal>
superior>=
superior or equalis
: check identity¶a = None
print(a is None)
print(a is not None)
True False
and
and or
¶True and True
True
True and False
False
False and False
False
True or True
True
True or False
True
False or False
False
float
(real, double precision) and complex
¶# float
a = float("1")
a = 1.234
a = 1e2
a = -1e-2
a = 0.2
# complex (2 floats)
c = complex("1")
c = 1 + 2j
print(c, c.real, c.imag)
(1+2j) 1.0 2.0
Remark: notation var_name.attr_name
to access to an attribute of an object.
b = 1e16
c = 1.2 + b
d = c - b
print(d)
2.0
Very general issue (not Python):
str
¶s = "hello"
s = "hello"
s = (
"How is it possible to write a very very "
"very long string with lines limited to 79 characters?"
)
s = """Strings on
more thand
one line.
"""
print(s)
Strings on more thand one line.
Warning: big difference between Python 2 and Python 3. In Python 3, str
are unicode and there is another type bytes
.
str
¶Objects of built-in types have methods associated with their type (object oriented programming). The built-in function dir
returns a list of name of the attributes. For a string, these attributes are python system attributes (with double-underscores) and several public methods:
s = "abcdef"
print(dir(s))
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isascii', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'removeprefix', 'removesuffix', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
Let's hide the internal variables starting and ending with __
(for now you don't need to understand the code used for that).
print([name_attr for name_attr in dir(s) if not name_attr.startswith("__")])
['capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isascii', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'removeprefix', 'removesuffix', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
To access an attribute of an object (here, the method str.startswith
), we use the dot:
s.startswith("a")
True
a = 1.23456789
"a = {}".format(a)
'a = 1.23456789'
"a = {:.4f}".format(a)
'a = 1.2346'
"a = {:8.4f}".format(a)
'a = 1.2346'
"a = {:.4e} (scientific notation)".format(a)
'a = 1.2346e+00 (scientific notation)'
print("{}\t{}\t{}".format(1, 2, 3))
1 2 3
a = 1.23456789
f"a = {a}"
'a = 1.23456789'
f"a = {a:.4f}"
'a = 1.2346'
f"a = {a:8.4f}"
'a = 1.2346'
f"a = {a:.4e} (scientific notation)"
'a = 1.2346e+00 (scientific notation)'
print(f"{1}\t{1+1}\t{2+1}")
1 2 3
s = "abcdef"
print("a" in s)
print("hello" not in s)
True True
print(s[0])
a
s[0] = 'b'
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-5-55620f378bce> in <module>()
----> 1 s[0] = 'b'
TypeError: 'str' object does not support item assignment
s[1:3]
'bc'
print((s.capitalize() + " " + s.upper() + "\n") * 4)
Abcdef ABCDEF Abcdef ABCDEF Abcdef ABCDEF Abcdef ABCDEF
Very general, can be used on all sequences as str
, list
, etc... Not simple for beginners but very powerfull (see here and here).
Python indexes and slices for a six-element str. Indexes enumerate the elements, slices enumerate the spaces between the elements.
Index from rear: -6 -5 -4 -3 -2 -1
Index from front: 0 1 2 3 4 5
+---+---+---+---+---+---+
| a | b | c | d | e | f |
+---+---+---+---+---+---+
Slice from front: 0 1 2 3 4 5 6
Slice from rear: -6 -5 -4 -3 -2 -1 None
s = "abcdef"
# s[start:stop:step]
s[2:6:2]
'ce'
# s[start:stop]
s[2:6]
'cdef'
# s[start:]
s[1:]
'bcdef'
# s[:stop]
s[:2]
'ab'
# step = -1: goes through the string in reverse order
s[::-1]
'fedcba'
list
¶A list is a mutable sequence of (possibly inhomogeneous) elements.
type([0, "a"])
list
# create an empty list
l = []
# fill the list (with the function append)
l.append("2")
# fill the list (with the function extend)
l.extend([6, 3.0])
print(l)
['2', 6, 3.0]
# concatenate lists with the operator +
print(l + ["hello", 3])
['2', 6, 3.0, 'hello', 3]
# get values
print(l[0], l[2], l[-2])
# slicing
print(l[0:2])
2 3.0 6 ['2', 6]
tuple
¶A tuple is a immutable sequence of (possibly inhomogeneous) elements.
Remark: when you need a sequence that won't be modified, tuple is usually more efficient than list.
t = 0, "a", 1.2
t1 = (5, "hello")
t2 = tuple([1.1, 2])
type(t)
tuple
t[1] # indexing
'a'
t[1:] # slicing
('a', 1.2)
a, b = t1 # tuple assigment
print(b)
hello
The objects of type str
, int
, float
, bool
are immutable. They can not be modified. Of course, a name that points towards an integer can point towards a different integer.
i = 1
i = i + 2 # (or i += 2)
print(i)
i = 10
print(i)
3 10
Here, the objects 1
and 3
have not been modified.
An object of type list
is mutable:
l = [0, 5]
print(l)
l.append("hello")
print(l)
[0, 5] [0, 5, 'hello']
Here, the object list tagged by the name l
has been modified inplace.
del
keyword¶del
removes a reference. If an object in not binded to any names, Python can delete it from its internal memory.
l = ["a", "b"]
del l[1]
print(l)
['a']
l = [0, 1, 2, 3, 4, 5]
l1 = l # assigment to a new name l1 (no copy of the object).
# the names l and l1 points towards the same object.
l1.append("a")
print(l1)
print(l)
[0, 1, 2, 3, 4, 5, 'a'] [0, 1, 2, 3, 4, 5, 'a']
l = [0, 1, 2, 3, 4, 5]
l1 = l[:] # shallow copy of l
l1.append("a")
print(l1)
print(l)
[0, 1, 2, 3, 4, 5, 'a'] [0, 1, 2, 3, 4, 5]
Other examples of slices for a six-element list. Indexes enumerate the elements, slices enumerate the spaces between the elements.
a = [0, 1, 2, 3, 4, 5]
all(
[
len(a) == 6,
a[1:] == [1, 2, 3, 4, 5],
a[:5] == [0, 1, 2, 3, 4],
a[0] == 0,
a[:-2] == [0, 1, 2, 3],
a[5] == 5,
a[1:2] == [1],
a[-1] == 5,
a[1:-1] == [1, 2, 3, 4],
a[-2] == 4,
]
)
True
Suppose we have the string containing header line.
s = " wind;temperature;;pressure "
str.strip
)str.find
and slicing)str.rfind
and slicing)";;" in ...
pattern)str.replace
)For each task, do not hesitate to print the help of the method by writing s.strip?
in IPython.
s = " wind;temperature;;pressure "
# remove leading blanks
s = s.strip()
f"--{s}--"
'--wind;temperature;;pressure--'
# extract the first field
idx = s.find(";")
s0 = s[0:idx]
s0
'wind'
# extract the second field
idx1 = s.find(";", idx + 1) # start the search after the first ";"
s1 = s[idx + 1 : idx1]
s1
'temperature'
# extract the last field
idx2 = s.rfind(";")
s2 = s[idx2 + 1 :]
s2
'pressure'
# check presence of ";;"
";;" in s
True
# remove empty field
s_no_empty = s.replace(";;", ";")
s_no_empty
'wind;temperature;pressure'
range
¶The function returns a range object:
# start, stop, step
range(1, 8, 2)
range(1, 8, 2)
We can make a list with the range object:
# start, stop, step
list(range(1, 8, 2))
[1, 3, 5, 7]
# start, stop (step=1)
list(range(2, 8))
[2, 3, 4, 5, 6, 7]
# stop argument (start=0, step=1)
list(range(8))
[0, 1, 2, 3, 4, 5, 6, 7]
Build a list of odd numbers in decreasing order.
if
, elif
, else
¶if expression:
statement(s)
else:
statement(s)
The statement contains the block of code that executes if the conditional expression in the if statement resolves to 1 or a TRUE value.
a = 0
if a == 0:
print("a is equal to 0.")
a is equal to 0.
a = 1
if a < 0:
print("a is negative.")
elif a == 0:
print("a is equal to 0.")
elif a > 0:
print("a is positive.")
else:
print("I don't know.")
a is positive.
while
¶i = 0
while i < 4:
i += 1
print("i =", i)
i = 4
i = 0
while i < 4:
i += 1
print("i =", i)
i = 1 i = 2 i = 3 i = 4
for
¶values = range(5)
for value in values:
print(value, end=", ")
0, 1, 2, 3, 4,
values = "abcd"
for ind in range(len(values)):
print(f"values[{ind}] = '{values[ind]}'", end="; ")
values[0] = 'a'; values[1] = 'b'; values[2] = 'c'; values[3] = 'd';
# the built-in function enumerate is very useful
for index, value in enumerate(["a", "b", "c"]):
print(f"({index}, {value})")
(0, a) (1, b) (2, c)
print(list(enumerate(["a", "b", "c"])))
[(0, 'a'), (1, 'b'), (2, 'c')]
continue
and break
¶continue
: passes the block in the loop and continues the loop.for x in range(1, 8):
if x == 5:
continue
print(x, end=", ")
1, 2, 3, 4, 6, 7,
break
: stop the loop.for x in range(1, 11):
if x == 5:
break
print(x, end=", ")
1, 2, 3, 4,
Edit a script with Spyder that calculates the average of a set of numbers. For example numbers = [67, 12, 2, 9, 23, 5]
sum
and len
sum
), using the keyword while
assert avg0 == avg1
Run the script
python
.numbers = [67, 12, 2, 9, 23, 5]
avg0 = sum(numbers) / len(numbers)
tmp = 0
i = 0
while i < len(numbers):
tmp += numbers[i]
i = i + 1
avg1 = tmp / len(numbers)
assert avg0 == avg1
We build a list:
from random import randint, shuffle
n = 20
i = randint(0, n - 1)
print("integer remove from the list:", i)
l = list(range(n))
l.remove(i)
shuffle(l)
print("shuffled list: ", l)
integer remove from the list: 10 shuffled list: [5, 14, 2, 17, 18, 13, 12, 4, 16, 6, 15, 7, 8, 1, 19, 0, 3, 11, 9]
One element has been removed:
l
).l
).# we can change ordering, let's sort
print(l)
l_sorted = sorted(l)
print(l_sorted)
found = None
for idx, elem in enumerate(l_sorted):
if elem != idx:
found = idx
break
if found is None:
found = len(l)
print("missing ", idx)
[5, 14, 2, 17, 18, 13, 12, 4, 16, 6, 15, 7, 8, 1, 19, 0, 3, 11, 9] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19] missing 10
# we cannot sort -> higher complexity
for elem in range(len(l) + 1):
if elem not in l:
break
print("missing ", elem)
missing 10
# another solution
actual_sum = sum(l)
len_l = len(l)
original_sum = (len_l + 1) * (len_l) // 2
print("missing ", original_sum - actual_sum)
missing 10
try
, except
syntax¶Exceptions and errors are common in all codes. There is a good system to handle them in Python.
Let's first see what gives such buggy code
l = ['a']
i = 1
print(l[i])
When these lines are executed, Python stops its execution and print a traceback:
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-30-8df9cec1a0ec> in <module>()
1 l = ['a']
2 i = 1
----> 3 print(l[i])
IndexError: list index out of range
try
, except
syntax¶Handling exception:
l = ["a"]
i = 1
try:
print(l[i])
except IndexError as e:
print(e)
list index out of range
Remark: never use
except:
It means "except all errors and exceptions". A user Control-C is an exception (KeyboardInterrupt
) so it would be caught and have no effect.
try:
...
except <exception1> as e1:
...
except <exception2> as e2:
...
else:
...
finally:
...
For each line of this string, append a variable of correct type in a list (i.e. "hello" should stay hello, 2 should become an int and 1.5 a float). Do it by catching errors.
Hints:
str_variables = """hello
1.5
2"""
the_list_you_should_get = ["hello", 1.5, 2]
split_list = []
for value in str_variables.split("\n"):
try:
value = int(value)
except ValueError:
print(value, "is not a int")
try:
value = float(value)
except ValueError:
print(value, "is not a float")
split_list.append(value)
print(split_list)
hello is not a int hello is not a float 1.5 is not a int ['hello', 1.5, 2]