Hello Data Types#

About Python, variable types and script execution. For interactive reading and executing code blocks Binder and find b01-pybase.ipynb, or install Python and JupyterLab locally.

Requirements for Local Usage

For running code locally, install Python along with an IDE that fits your needs and preferences.

Load Python Environment#

These pages are written with JupyterLab https://jupyter.org/assets/homepage/main-logo.svg. For the best learning experience make sure to read about Integrated Development Environments (IDEs) before starting this tutorial.

The First Lines of Code#

The examples in the first steps revolve around ice cream to illustrate the utility of simple code snippets. If you do not like ice cream, replace it with your favorite category of things.

How to Run Python

The very first thing you need to run Python code is, obviously, Python itself. Python can be started in a standard (system) terminal or a terminal of an IDE. Make sure to use a standard terminal for your platform according to the Python installation descriptions. For instance:

  • On Windows, click on the start menu, tap Anaconda Prompt, and hit Enter

  • On Linux, open the system Terminal (e.g., Gnome Terminal by pressing Ctrl + Alt + T - if nothing happens, have a look at the Linux Terminal introduction)

  • On macOS, find the Terminal (or Command Line Tools), tap Python, and hit Enter

Alternatively, use your favorite IDE to run Python code in a terminal environment:

  • With PyCharm (Windows):

    • Create a new empty project and use the flusstools environment (read how to get it and how to create a PyCharm project)

    • Find and click on the Python Console tab at the bottom of the PyCharm window

    • The Python console is now ready to use.

  • With Jupyter (cross-platform):

    • Open a Terminal following the above descriptions

    • Enter jupyter-lab (or jupyter lab, or jupyterlab, or jupyter notebook depending on your installation) > Jupyter opens in your web browser

    • Navigate to a local copy of this Jupyter notebook and run any code block (click on a code block and hit the run triangle button in the top menu).

Ultimately, you are ready to get the very first “feedback” (callback) from the Python console. Start with a simple call of the print function by entering:

print("This is callback from the digital ice cream printer.")

Recall that the print command, like all other Python commands that will follow, can be either run in a Python console (e.g., Conda Prompt on Windows or Terminal on Linux) or in your favorite IDE. In addition, we can write down the print command in a Python file ending on .py (e.g., icecream_tutorial.py) and run the file. For instance, in PyCharm:

  • Expand the project branch (if not yet done: on the left side of the window)

  • Right-click in the project folder, select New > Python File and name the new Python (.py) file (e.g., icecream_tutorial.py).

  • Copy the above print("...") code into the new Python file and save it.

  • Right-click in the Python file, then Run icecream_tutorial.py (alternatively: press the Ctrl + Shift + F10 keys).

  • Now, the Python Console should pop up at the bottom of the window and it will print the text in the above print command.

In any other (IDE) Terminal, cd to the directory where the Python file (icecream_tutorial.py) lives, then enter python icecream_tutorial.py and hit Enter.


In the following, there will not be any more differentiation between using PyCharm or any other IDE and Jupyter. Thus, Run the script/code block means: run the script in your favorite IDE in the following.

With the " apostrophes in the print command, we pass a string variable to the print command. Instead of using ", one can also use ', but it is important to use the same type of apostrophe at the beginning and the end of the string (text) variable.


Be reasonable with the usage of print. Especially in loops, print leads to unnecessary system load and slows down the script.

A marginal note: In Python3 print is a function, not a keyword as in Python2. print is useful, for example, to make a script show where it is currently running. It is also possible to print other types of variables than strings, but the combination of numerical and text variables requires more encoding (see next sections).

Python Variables and Data Types#

The above-shown print function already involved string variables. In addition, there are a couple of other variable (data) types in Python:

  • text

  • boolean

  • number (numeric)

  • tuple

  • list

  • dictionary


Data and variable types are difficult to understand if you simply try to learn them by heart. Remember that different data types can be useful when writing code for a particular solution.


Text variables in Python are strings (str) that consist of multiple characters (chr):






String embraced with double quotes


String embraced with single quotes


Literal string (multi-line text)



Character (unit of a string)

| Type | Example     | Description                        |
| str  | `"apple"`   | String embraced with double quotes |
|      | `'apple'`   | String embraced with single quotes |
|      | `"""apple"""` | Literal string (multi-line text) |
| chr  | `"a"`       | Character (unit of a string)       |

In addition, string variables have some built-in functions that facilitate coding. To create (instantiate) a string variable, use the = sign as follows:

flavor1 = "vanilla" # str
first_letter = "v" # str / char

Characters can be converted to numbers and the other way round. This feature can be useful in loops to iterate for example over alphabetically ordered lists (attention: the conversion depends on how your operating system is configured).

print(int("c", 36)) # use int(letter, literal)


Boolean variables are either True (1) or False (0) with many useful code implementations. We will come back to booelans (bool) later in the section on conditional (if ...) statements.

bowl = False
print("The bowl exists: " + str(bowl))

Numbers (Numeric)#

Python knows a couple of different numeric data types:






Signed Integer



Floating point real number



Complex number where J is in the range between 0 and 255

To create a numeric variable, use the = sign as follows:

scoops = 2 # int
weight = 0.453 # float

Python does not require a type assignment for a variable because it is a high-level, interpreted programming language (other than, for example, C++). However, once a variable was assigned a data type, do not change it in the code (it is just good practice - so that scoops remain integers).

If a print statement combines numeric and text variables, the numeric variables first have to be converted to text, and then concatenated to a string. There are several ways to combine multiple variables in a text string:

print("My ice cream consists of %d scoops." % scoops) # use %d for integers, %f for floats and %s for strings
print("My ice cream weighs %1.3f kg." % weight)
print("My ice cream weighs " + str(weight) + " kg.")
print("My ice cream weighs {0} kg and has {1} scoops".format(weight * scoops, scoops)) # multiple variable conversion
print("My ice cream weighs " + weight + " kg.") # this cannot work because weight is a float


A list is a series of values, which is embraced with brackets []. The values can be any other data type (i.e., numeric, text, dictionary, or tuple), or even another list (so-called nested lists).

flavors = ["chocolate", "bread", flavor1] # a list of strings
nested_list = [[1, 2, 3], ["a", "b", "c"]]
print("A list of strings: " + str(list("ABC")))

The items of a list are called entries and entries can be appended, inserted, or deleted from a list.


Python always starts counting from zero. Thus, the first entry of a list is entry number 0.

Also lists have many useful built-in functions:

flavors.append("cherry") # append an entry at the end
flavors.insert(0, "lemon") # insert an entry at position 0
print("There are %d flavors in my list." % flavors.__len__())
print(*flavors) # print all elements in list - dows not work in combination with str
print("This is all I have: " + str(flavors[:]).strip("[]"))
flavors.__delitem__(2) # bread is not a flavor, so let's remove it
print("This is all I have: " + ", ".join(flavors))      


A tuple represents a collection of Python objects, similar to a list, and the sequence of values (data types) in a tuple can take any type. Elements of a tuple are also indexed with integers. In contrast to lists, a tuple is embraced with round parentheses () and a tuple is immutable while lists are mutable. This means that a tuple object can no longer be modified after it has been created. So why would you like to use tuples then? The answer is that a tuple is more memory efficient than a mutable object because the immutable tuple can create references to existing objects. In addition, a tuple can serve as a key of a dictionary (see below), which is not possible with a list.

a_tuple = ("a text element", 1, 3.03) # example tuple
print(a_tuple[-1]) # last element of a tuple (this also works with lists ..)

# comparison of lists and tuples
import time # we need this package (module here) and we will learn more about modules later
print("patience ...")

# iterate over a list with 100000 elements
start_time = time.perf_counter()
a_list = [] # empty list
x = range(100000)
for item in x: a_list.append(item)
print("Run time with list: " + str(time.perf_counter() - start_time) + " seconds.")

# iterate over a tuple with 100000 elements with modifying the tuple
start_time = time.perf_counter()
new_tuple = () # empty tuple
x = range(100000)
for item in x: new_tuple = new_tuple + (item,)
print("Run time with tuple modification: " + str(time.perf_counter() - start_time) + " seconds.")

# iterate over a tuple with 100000 elements if no modification of the tuple is needed
start_time = time.perf_counter()
new_tuple = tuple(range(100000)) 
for item in new_tuple: pass
print("Run time without tuple modification: " + str(time.perf_counter() - start_time) + " seconds.")


Dictionaries are a powerful data type in Python and have the basic structure my_dict = {key: value}. In contrast to lists, an element of a dictionary is called by invoking a key rather than an entry number. A dictionary is not enumerated and keys just point to their values (whatever data type the value is).

my_dict =  {1: "Value 1", 2: "Value 2"}
another_dict = {"list1": [1, 2, 3], "number2": 1}
my_dict [1]

Also dictionaries have many useful built-in functions:

my_dict.update({3: "Value 3"})  # add a dictionary element 
my_dict.__delitem__(1) # delete a dictionary element 
my_dict.__len__() # get the length (number of dictionary elements)

In addition, two lists of the same length can be zipped into a dictionary:

weight = [0.5, 1.0, 1.5, 2.0]
price = [1, 1.5, 1.8, 2.0]
apple_weight_price = dict(zip(weight, price))
print("{0} kg apples cost EUR {1}.".format(weight[2], apple_weight_price[weight[2]]))


A Python set is a mutable object that is instantiated with curly brackets. Sets are unordered (in contrast to lists and tuples), and therefore, useful for mathematical operations, such as the union, intersection, difference, or symmetric difference of sets of elements. The below code block features the instantiation of two sets and the application of mathematical operators.

ice_shop_a = {"vanilla", "chocolate", "green"}
ice_shop_b = {"blue", "chocolate", "vanilla"}

print("Ice shops united: " + str(ice_shop_a | ice_shop_b))
print("Both shops intersectedly offer: " + str(ice_shop_a & ice_shop_b))
print("This is what shop a has, but not shop b: " + str(ice_shop_a - ice_shop_b))
print("This is what shop b has, but not shop a: " + str(ice_shop_b.difference(ice_shop_a)))
print("This is what is unique to both shops (symmetric difference): " + str(ice_shop_a ^ ice_shop_b))
Ice shops united: {'blue', 'green', 'vanilla', 'chocolate'}
Both shops intersectedly offer: {'chocolate', 'vanilla'}
This is what shop a has, but not shop b: {'green'}
This is what shop b has, but not shop a: {'blue'}
This is what is unique to both shops (symmetric difference): {'green', 'blue'}


How to initialize an empty set

Writing new_variable = {} instantiates an empty dictionary, not a set. Thus, to initialize an empty set, write new_set = set().


A frozenset can be created with frozenset(set) and has the characteristics of a set, but its elements cannot be modified once assigned. Similar to tuples that are immutable lists, frozensets are immutable sets. Why can it make sense to use a frozenset? Because a set is mutable and unhashable, which is why it cannot be used as dictionary keys as opposed to frozensets that are hashable and can be used as keys to a dictionary.


The following operators compare data types and output boolean values (Trueor False):

  • a == b or a is b a equals / is b

  • a and b a and b

  • a or b a or b

  • a <= b a smaller than or equal to b (similar without equal sign)

  • a >= b a larger than or equal to b (similar without equal sign)

  • a in b a in b (meaningful in stings - see example below)

print(not False)
print(1 is 1) # is
print(1 is 2)
print("ice" in "ice cream")