Python Basics#

1. Intro: What is Python?#

  • Python is a high-level, interpreted, and object-oriented programming language. It comes with powerful built-in data structures and supports dynamic typing and late binding, which makes it ideal for rapid application development and for use as a scripting language to connect different components.

  • Its clear and readable syntax makes Python easy to learn and maintain. It also supports modules and packages, which promote modular design and code reuse.

  • Python is free and open source. Both its interpreter and extensive standard library are available in source or binary form for all major platforms, and can be freely distributed.

đź“– Learn more at python.org.

2. Data types#

a) Numbers#

Basic operations:

# Addition
1 + 1
2
# Multiplication
1 * 3
3
# Division
1 / 2
0.5
# Exponentiation
2 ** 4
16
# Modulo
5 % 2
1
# Bracket
(2 + 3) * (5 + 5)
50
# Assignment
x = 2
y = 3
z = x + y
z
5

b) Strings#

# Single Quotes
'single quotes'
# Double Quotes
"double quotes"
# Mixed Form
"It's easy to mix it up."
"It's easy to mix it up."
# Printing
x = 'Hello'
x
'Hello'
print(x)
Hello
# Using variables in print command
num = 21
name = 'Emma'
print('My age is: {}, my name is: {}'.format(num,name))
My age is: 21, my name is: Emma
print('My age is: {1}, my name is: {0}'.format(num,name))
My age is: Emma, my name is: 21
print('My age is: {two}, my name is: {one}'.format(one=num,two=name))
My age is: Emma, my name is: 21
print('My age is: ' + str(num) + ', my name is: ' + name)
My age is: 21, my name is: Emma
print('My age is: %s, my name is: %s' % (num, name))
My age is: 21, my name is: Emma

\(\Rightarrow\) More info can be found here: https://pyformat.info/

c) Lists#

# Lists are created with square brackets
[1, 2, 3]

# Nesting is possible
['hi', 1, [1, 2]]
['hi', 1, [1, 2]]
# For later reuse: let us assign a variable
my_list = ['a', 'b', 'c']
# Append another entry
my_list.append('d')
# Strings and numbers can be mixed
my_list.append(5)
# Show
my_list
['a', 'b', 'c', 'd', 5]
# Output the first element (attention: python index starts from 0 !!!)
my_list[0]
'a'
# Output the second element
my_list[1]
'b'
# Output the elements starting from the second one
my_list[1:]
['b', 'c', 'd', 5]
# In using `my_list[a:b]`, the last element (b) is excluded, i.e., the following only returns the element with index 0 (which is the first element).
my_list[:1]
['a']
# `-1` is the first element from the back, i.e., the last element.
my_list[-1]
5
my_list[-2:]
['d', 5]
# After :: you can choose step length
my_list[1::2]
['b', 'd']
# :: can be used to reverse order.
my_list[1::-1]
['b', 'a']
my_list[4::-2]
[5, 'c', 'a']
my_list[0] = 'NEW'
my_list
['NEW', 'b', 'c', 'd', 5]
# Example of a nested list
nest = [1, 2, 3, [4, 5, ['target']]]
# The fourth element (with index 3) is a list
nest[3]
[4, 5, ['target']]
# The third element (with index 2) is a list
nest[3][2]
['target']
# The first element is string 'target'
nest[3][2][0]
'target'
# Strings are lists in python; you can access their elements via []
nest[3][2][0][2]
'r'
# What is the index of element '2'? (in R: which())
nest.index(2)
1

d) Dictionaries#

A dictionary can be created via “{}”.
Individual entries are separated by commas.
Each entry consists of a key-value pair.
The key is a string; the value can be anything.

d = {'key1': 'value1', 'key2': 'value2'}
d
{'key1': 'value1', 'key2': 'value2'}
d2 = {'key1': 'value1', 'key2': 2}
d2
{'key1': 'value1', 'key2': 2}
# An element is accessed via the key
d['key1']
'value1'
d2['key2']
2
# Get all the dictionary keys:
d.keys()
dict_keys(['key1', 'key2'])
# To access via indices, the dict_keys should be first converted to a list:
list(d.keys())[1]
'key2'
# Get all the dictionary values:
d.values()
dict_values(['value1', 'value2'])
# Get all the dictionary items, i.e. key-value pairs:
d.items()
dict_items([('key1', 'value1'), ('key2', 'value2')])

e) Tuples#

# A tuple can be generated via ()
t = (1,2,3)
# A tuple is like a list, e.g., accessed via [] ...
t[0]
1
#... but its values cannot be overwritten
t[0] = 'NEW'
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[42], line 2
      1 #... but its values cannot be overwritten
----> 2 t[0] = 'NEW'

TypeError: 'tuple' object does not support item assignment

f) Sets#

# A set can be generated via {}
set1 = {1,2,3}
# A set ignores the repetitive elements
set2 = {1,2,3,1,2,1,2,3,3,3,3,2,2,2,1,1,2}
print(set1)
{1, 2, 3}
print(set2)
{1, 2, 3}
# Function set() can be used to create a set from a list
set3 = set([1,3,5,3,1])
print(set3)
{1, 3, 5}
# Operations on sets:
# Union
set1 | set3
{1, 2, 3, 5}
# Intersection
set1 & set3
{1, 3}
# Difference
print(set1 - set3)
print(set3 - set1)
{2}
{5}
# Symmetric Difference
set1 ^ set3
{2, 5}

g) Booleans#

# Python Booleans are True and False (Python is case-sensitive)
True; False
False

3. Comparison operators#

# Comparison operators are similar to the ones in R:
# Greater than
1 > 2
False
# Less than
1 < 2
True
# Greater or equal
1 >= 1
True
# Less than or equal
1 <= 4
True
# Equal
1 == 1
True
# Unequal
"hi" != "hey"
True

4. Logical operators#

# And
(1 > 2) and (2 < 3)
False
# Or
print((1 > 2) or (2 < 3))
print((1 == 2) or (2 == 3) or (4 == 4))
True
True
# "Is an element of"
'x' in [1,2,3]
False
'x' in ['x','y','z']
True
# Use "not" for negation
not('x' in ['x','y','z'])
False

5. if-statements#

Unlike many other programming languages (e.g., R), Python relies on indentation to define code blocks instead of using curly brackets {}.

# If-Statement
if 1 < 2:
    print('Yes!')
Yes!
# If - Else
if 1 < 2:
    print('first')
else:
    print('last')
first
if 1 == 2:
    print('first')
else:
    if 3 == 3:
        print('middle')
    else:
        print('last')
middle
# Else if is abbreviated to elif
if 1 == 2:
    print('first')
elif 3 == 3:
    print('middle')
else:
    print('last')
middle

6. Loops#

a) for-loop#

# Define a list to iterate over:
seq = [1,2,3,4,5]

# The logic is as in R, but brackets are not needed;
# indentation is part of the syntax:
for item in seq:
    print(item)
1
2
3
4
5

b) while-loop#

# The idea is as usual, again with sparse syntax
i = 1
while i < 5:
    print('i is now: {}'.format(i))
    i += 1 # or i = i+1
i is now: 1
i is now: 2
i is now: 3
i is now: 4
print('Loop is over, i is: ' + str(i))
Loop is over, i is: 5

c) range()-function#

# range(n) creates an object that can be used for iteration;
# similar to seq_len(n) in R:
range(5)
range(0, 5)
for i in range(5):
    print(i)
0
1
2
3
4
# Unlike the seq_len(n), range(n) is not a vector / list.
# To print the elements, first convert range(n) into a list:
r = range(5)
rl = list(range(5))
print(rl)
[0, 1, 2, 3, 4]
# Range from ... to ... (attention: the last element is excluded again)
list(range(5, 20))
[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

7. List comprehensions#

# One cannot directly apply arithmetic operations to lists
# (unlike R-vectors):
x = [1,2,3,4]
x ** 2
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[88], line 4
      1 # One cannot directly apply arithmetic operations to lists
      2 # (unlike R-vectors):
      3 x = [1,2,3,4]
----> 4 x ** 2

TypeError: unsupported operand type(s) for ** or pow(): 'list' and 'int'
# A complicated alternative would be: (it can be even more complicated)
out = []
for item in x:
    out.append(item**2)
print(out)
[1, 4, 9, 16]
# A shorter alternative is List Comprehensions;
# a shortened version of the for-loop:
y = [item**2 for item in x]
print(y)
[1, 4, 9, 16]
# List comprehensions can be supplemented with with "if" and "else":
y = [0 if item < 2.5 else 1 for item in x]
print(x)
print(y)
[1, 2, 3, 4]
[0, 0, 1, 1]

8. Functions#

# A function is defined via the keyword 'def',
# followed by the function name and its parameters:
def my_func(param1 = 'default'):
    """
    Here the so-called docstring appears, a kind of help for functions.
    """
    print(param1)
    
# Show the function:
my_func
<function __main__.my_func(param1='default')>
# You can check the docstring of a function via help():
help(my_func)
Help on function my_func in module __main__:

my_func(param1='default')
    Here the so-called docstring appears, a kind of help for functions.
# Execute the function with its default parameter:
my_func()
default
# Execute the function with a new parameter:
my_func('new param')
new param
# When the function has more than one parameter, it is better to
# explicitly state the parameter you specify
my_func(param1 = 'new param')
new param

Functions can return values of any type (e.g., integers, strings, lists, or even other functions). The return statement specifies what a function outputs, and if omitted, the function returns None by default.

# A function with two parameters and return
def power(x, m = 2):
    return x**m
out = power(2, 3)
print(out)
8

None is the sole instance of Python’s NoneType, representing the absence of a value. It is commonly used:

  • To indicate “no value” or “not yet assigned” in variables or data structures.

  • As a placeholder in optional function arguments.

  • For flow control, such as checking if a value has been set.

def find_value(dictionary, key):
    return dictionary.get(key)  # Returns None if key is missing

result = find_value({"a": 1}, "b")
print(result is None)
True

9. Methods for strings#

# Everything in lower case
st = 'Hello world, Good Morning'
st.lower()
'hello world, good morning'
# Everything in capital letters
st.upper()
'HELLO WORLD, GOOD MORNING'
# Split words => list of individual words
st.split()
['Hello', 'world,', 'Good', 'Morning']
# Split on a certain character
st.split(',')
['Hello world', ' Good Morning']
st.split(',')[1]
' Good Morning'