1.4.1. Data types#

In this section, we showcase the different Python built-in data types.

For an exhaustive explanation of the different types and their operations, we suggest reading the official Built-in Types documentation.

1.4.1.1. Boolean#

The bool type is used to represent truthy value of an item.

1.4.1.1.1. Operations#

Operation

Result

Notes

x or y

if x is false, then y, else x

(1)

x and y

if x is false, then x, else y

(2)

not x

if x is false, then True, else False

(3)

  1. Short-circuit operation. Only evaluates the second operation if the first one is false.

  2. Short-circuit operation. Only evaluates the second operation if the first one is true.

  3. not has a lower priority than non-Boolean operator. i.e. not a == b is the same as not (a == b).

Operation

Meaning

<

strictly less than

<=

less than or equal

>

strictly greater than

>=

greater than or equal

==

equal

!=

not equal

is

object identity

is not

negated object identity

1.4.1.1.2. Examples#

# Assignment
x: bool = True
y: bool = False
print(f"""Boolean Operations (and, or, not)
{(x or y)=}
{(x and y)=}
{(x and True)=}
{(not x)=}
""")
Boolean Operations (and, or, not)
(x or y)=True
(x and y)=False
(x and True)=True
(not x)=False
surname: str = "John"
lastname: str = "Doe"

a: int = 10
b: float = 10.0

print(f"""Boolean Operations (Comparisons)

{(len(surname) < len(lastname))=}
{(a == b)=}
{(type(a) == type(b))=}
""")
Boolean Operations (Comparisons)

(len(surname) < len(lastname))=False
(a == b)=True
(type(a) == type(b))=False

Caution with the is operand

from pathlib import Path

# Integer type is immutable
a: int = 10
b: int = 10

# List type is mutable
l1: list = [1, 2, 3]
l2 = l1

print(f"""Binary Operations (is operand)

{(a is b)=}
{(l1 is l2)=}
{(l1 is [1, 2, 3])=}
""")
Binary Operations (is operand)

(a is b)=True
(l1 is l2)=True
(l1 is [1, 2, 3])=False

1.4.1.2. Numeric#

There are three numeric types used to represent numbers: int, float, and complex.

1.4.1.2.1. Operations#

Operation

Result

x + y

sum of x and y

x - y

difference of x and y

x * y

product of x and y

x / y

quotient of x and y

x // y

floored quotient of x and y

x % y

remainder of x / y

-x

x negated

abs(x)

absolute value or magnitude of x

int(x)

x converted to integer

float(x)

x converted to floating point

x ** y

x to the power y

1.4.1.2.2. Example#

# Assignment
a: int = 7
b: float = 19.0
c: complex = 5 + 23j

print(f"""
{a=}
{b=}
{c=}
""")
a=7
b=19.0
c=(5+23j)
print(f"""Numeric Operations

{(a+c)=}
{(a/2)=}
{(a//2)=}
{(b%2)=}
{(10**4)=}
""")
Numeric Operations

(a+c)=(12+23j)
(a/2)=3.5
(a//2)=3
(b%2)=1.0
(10**4)=10000

1.4.1.3. Sequence#

There are three types used to represent an ordered collection of items: list, tuple, and range.

While list are mutable, tuple and range are immutable.

1.4.1.3.1. Operations#

Operation

Result

x in s

True if an item of s is equal to x, else False

x not in s

False if an item of s is equal to x, else True

s + t

the concatenation of s and t

s * n or n * s

equivalent to adding s to itself n times

s[i]

ith item of s, origin 0

s[i:j]

slice of s from i to j

s[i:j:k]

slice of s from i to j with step k

len(s)

length of s

min(s)

smallest item of s

max(s)

largest item of s

s.index(x[, i[, j]])

index of the first occurrence of x in s (at or after index i and before index j)

s.count(x)

total number of occurrences of x in s

1.4.1.3.2. Examples#

# Assignment
l1: list = [2, 3, 5, 7, 11]
t1: tuple = (1, 3, 5, 7, 9, 11)
r1: range = range(1, 11+1, 2)

print(f"""
{l1=}
{t1=}
{r1=}
{list(r1)=}
""")
l1=[2, 3, 5, 7, 11]
t1=(1, 3, 5, 7, 9, 11)
r1=range(1, 12, 2)
list(r1)=[1, 3, 5, 7, 9, 11]
1 in l1, 2 in l1
(False, True)
l1 + t1
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[9], line 1
----> 1 l1 + t1

TypeError: can only concatenate list (not "tuple") to list
sorted(l1 + list(t1))
[1, 2, 3, 3, 5, 5, 7, 7, 9, 11, 11]
[5] * 3
[5, 5, 5]
print(f"""Sequence attributes
{len(l1)=}
{min(l1)=}
{max(l1)=}
{l1[:3]=}
{l1[3:]=}
{l1[::2]=}
""")
Sequence attributes
len(l1)=5
min(l1)=2
max(l1)=11
l1[:3]=[2, 3, 5]
l1[3:]=[7, 11]
l1[::2]=[2, 5, 11]

1.4.1.3.3. List Comprehensions#

List comprehensions is a concise way to create list.
The list elements are defined within brackets followed by a for clause, then one or more for or if clauses.

print(
    [n**3 for n in range(100) if n%7 == 0 ]
)
[0, 343, 2744, 9261, 21952, 42875, 74088, 117649, 175616, 250047, 343000, 456533, 592704, 753571, 941192]

1.4.1.4. Text#

The str type is used to represent an immutable sequence of characters.

1.4.1.4.1. Example#

print('allows embedded "double" quotes')
print("allows embedded 'single' quotes")
print("escape \"quote\" character")
print("""-----------------------
This is a multi line
sequence of characters
""")
allows embedded "double" quotes
allows embedded 'single' quotes
escape "quote" character
-----------------------
This is a multi line
sequence of characters
# Assignment
sentence: str = "This is a short sentence."

str content

sentence.endswith("World!")
False
sentence.startswith("Th")
True
"           empty space          ".strip()
'empty space'
"           empty space          ".strip("e ")
'mpty spac'

str manipulation

sentence.split()
['This', 'is', 'a', 'short', 'sentence.']
"_".join(sentence.split())
'This_is_a_short_sentence.'

Similar to sequence types, we can slice strings.

sentence[:10]
'This is a '

1.4.1.4.1.1. f-strings#

Python allows string to be formatted with variables. f-strings are one way to do that.

name = input()
print(f"{name=}")
print(f"My name is {name.capitalize()}")
name='math'
My name is Math

1.4.1.5. Map#

The dict type is used to map a collection of keys to their respective value.

from pprint import pprint


# Assignment
d1: dict = {"banana": "yellow", "orange": "orange", "apple": "green"}
pprint(d1)
{'apple': 'green', 'banana': 'yellow', 'orange': 'orange'}

dict content

d1.items()
dict_items([('banana', 'yellow'), ('orange', 'orange'), ('apple', 'green')])
d1.keys()
dict_keys(['banana', 'orange', 'apple'])
d1.values()
dict_values(['yellow', 'orange', 'green'])
"apple" in d1, "peach" in d1
(True, False)
d1.get("apple"), d1.get("peach")
('green', None)
d1["apple"]
'green'

Remove an element from dict

pprint(d1)
del d1["banana"]
pprint(d1)
{'apple': 'green', 'banana': 'yellow', 'orange': 'orange'}
{'apple': 'green', 'orange': 'orange'}
d1["banana"] = "yellow"
pprint(d1)
{'apple': 'green', 'banana': 'yellow', 'orange': 'orange'}

Merging dictionaries

d2: dict = {"banana": "green", "apple": "red"}

d2.update(d1)
d2
{'banana': 'green', 'apple': 'green', 'orange': 'orange'}
d2: dict = {"banana": "green", "apple": "red"}

d2 | d1
{'banana': 'green', 'apple': 'green', 'orange': 'orange'}

Allowing empty key to return a value with collections.defaultdict

from collections import defaultdict

d3: defaultdict = defaultdict(int)
pprint(d3)
defaultdict(<class 'int'>, {})
d3[1] = 1
d3[2] = 4

d3[3]
0
pprint(d3)
defaultdict(<class 'int'>, {1: 1, 2: 4, 3: 0})

1.4.1.5.1. Dictionary Comprehension#

Similar to list comprehension, we can use curly brackets to use dict comprehension.

print(
    {
    x: x**2
    for x in range(10)
    }
)
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}

1.4.1.6. Set#

There are two types is used to represent an unordered collection of items: set and frozenset

set are mutable object and not hashable, while frozenset are immutable and hashable.
This means that frozenset can be used as a dictionary key.

# Assignment
odds: set = {1, 3, 5, 7 , 9}
evens: set = {2, 4, 6, 8, 10}
primes: set = {2, 3, 5, 7}
print(f"""Set Operations

{"Union difference:": >25} {(odds | evens)=}
{"Intersection difference:": >25} {(odds & primes)=}
{"Difference:": >25} {(primes - odds)=}
{"Difference:": >25} {(odds - primes)=}
{"Symmetrical difference:": >25} {(primes ^ odds)=}
""")
Set Operations

        Union difference: (odds | evens)={1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
 Intersection difference: (odds & primes)={3, 5, 7}
              Difference: (primes - odds)={2}
              Difference: (odds - primes)={1, 9}
  Symmetrical difference: (primes ^ odds)={1, 2, 9}

1.4.1.7. None#

The null value is represented by the NoneType

from pathlib import Path

# Assignment
git_config: None = None

print(f"""
{git_config=}
{(git_config is None)=}
""")

# Assign the proper path
git_config: Path = Path().home() / ".gitconfig"
print(f"""
{git_config=}
{(git_config is None)=}
""")
git_config=None
(git_config is None)=True


git_config=PosixPath('/home/math/.gitconfig')
(git_config is None)=False