Python Basics – Part 9: Tuples, Dictionaries, and Comprehensions

Tuples, Dictionaries, and Comprehensions in Python

In this week’s Python training notes, we continue exploring core data structures and essential programming patterns.
We’ll look at Tuples, Dictionaries, Comprehensions, and a few handy built-in mathematical functions that make data handling smoother.

Tuples in Python

A tuple is similar to a list, but it’s immutable — its content cannot be changed after creation.
In database terms, a tuple is like a record (a single row of data).

tuple1 = (11, 12, 13)
print(tuple1)         # (11, 12, 13)
print(type(tuple1))   # <class 'tuple'>
print(tuple1[0])      # 11

Trying to change a tuple value raises an error:

tuple1[0] = 42  # TypeError: 'tuple' object does not support item assignment

Tuples can contain mixed data types:

tuple2 = (1, 2.2, True, 'Hello', [1, 2], (3, 4))
print(tuple2)

Creating tuples from sequences:

print(tuple([1, 2, 3]))       # (1, 2, 3)
print(tuple('Hello'))         # ('H', 'e', 'l', 'l', 'o')
print(tuple(range(4, 19, 3))) # (4, 7, 10, 13, 16)

Empty and single-element tuples:

empty = ()
print(type(empty))   # <class 'tuple'>

single = (5)
print(type(single))  # int
single = (5,)
print(type(single))  # tuple

Tuple unpacking:

person = ("Cloe", "Morningstar", 39)
first, last, age = person
print(first, age)  # Cloe 39

Tuple methods:

numbers = (11, 12, 13, 12, 11, 14, 12)
print(numbers.count(12))  # 3
print(numbers.index(12))  # 1
print(numbers.index(12, 3))  # start search from index 3

Quick value swap (Pythonic one-liner):

a, b = 12, 42
a, b = b, a
print(a, b)  # 42 12

Else After Loops

The else clause after a loop runs only if the loop completes without hitting a break.

from random import randint

c = 1
while c <= 4:
    if randint(1,6) == 6:
        print('Rolled a 6 after', c, 'tries — break')
        break
    c += 1
else:
    print('No six rolled!')

Mathematical Functions

Absolute Value

print(abs(-10))   # 10

Exponentiation

print(2 ** 8)     # 256
print(pow(2, 8))  # 256

math.pow() always returns a float:

import math
print(math.pow(2, 3))  # 8.0

Quotient and Remainder

print(divmod(13, 5))  # (2, 3)

Square Root and Factorial

print(math.sqrt(64))     # 8.0
print(math.factorial(5)) # 120

Common Constants

print(math.pi)  # 3.141592653589793
print(math.e)   # 2.718281828459045

Rounding helpers:

print(math.ceil(9.1))   # 10
print(math.floor(9.9))  # 9
print(math.trunc(-7.8)) # -7

Dictionaries in Python

A dictionary stores data as key–value pairs.
It’s mutable and can hold different types of keys and values.

person = {'first_name': 'Cloe', 'last_name': 'Morningstar'}
print(person)           # {'first_name': 'Cloe', 'last_name': 'Morningstar'}
print(person['first_name'])  # Cloe

Adding and modifying values:

person['age'] = 39
person['first_name'] = 'Lucifer'

Creating a dictionary with dict():

city = dict([('France', 'Paris'), ('Germany', 'Berlin')])
print(city['France'])  # Paris

person = dict(first_name='Cloe', last_name='Morningstar')
print(person)

Tuple as a dictionary key (since tuples are immutable):

contacts = {
    ('Lucifer', 'Morningstar'): '+123456789',
    ('Cloe', 'Morningstar'): '+12345676759'
}
print(contacts[('Cloe', 'Morningstar')])

Accessing and removing data:

print(person.get('first_name'))  # Cloe
print(person.pop('last_name'))   # Morningstar
person.clear()

Useful methods:

print(person.keys())    # dict_keys(['first_name', 'age'])
print(person.values())  # dict_values(['Cloe', 39])
print(person.items())   # dict_items([('first_name', 'Cloe'), ('age', 39)])

Looping through a dictionary:

for key, value in person.items():
    print(f"{key}: {value}")

Dictionary comprehension:

squares = {x: x**2 for x in range(5)}
print(squares)  # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

Other useful tools:

d = {'name': 'Cloe'}
d.update({'age': 39})
print(d)  # {'name': 'Cloe', 'age': 39}

copy_d = d.copy()
print(copy_d is d)  # False

keys = ['a', 'b', 'c']
print(dict.fromkeys(keys, 0))  # {'a': 0, 'b': 0, 'c': 0}

List Comprehensions

Comprehensions provide a concise way to create lists.

Traditional loop:

result = []
for i in range(2, 6):
    result.append(i ** 2)
print(result)  # [4, 9, 16, 25]

Comprehension version:

result = [i ** 2 for i in range(2, 6)]
print(result)  # [4, 9, 16, 25]

Tuples in list comprehensions:

pairs = [(i, i ** 2) for i in range(2, 6)]
print(pairs)  # [(2, 4), (3, 9), (4, 16), (5, 25)]

With conditions:

under_100 = [i ** 2 for i in range(2, 20) if i ** 2 < 100]
print(under_100)

Conditional expression:

nums = [x if x % 2 == 0 else -x for x in range(5)]
print(nums)  # [0, -1, 2, -3, 4]

Nested comprehension:

matrix = [[i * j for j in range(3)] for i in range(3)]

Set and dictionary comprehensions:

unique_letters = {x for x in 'banana'}
square_dict = {x: x**2 for x in range(3)}

List Operators

List concatenation and repetition:

a = [1, 2, 3]
b = [4, 5, 6]
c = a + b
print(c)  # [1, 2, 3, 4, 5, 6]

The + operator creates a new list, leaving the originals unchanged.

The * operator repeats a list:

l = [1, 2, 3]
print(l * 3)  # [1, 2, 3, 1, 2, 3, 1, 2, 3]

Be careful with nested lists — it creates shallow copies:

lst = [[0]] * 3
lst[0][0] = 99
print(lst)  # [[99], [99], [99]]

Safer version:

lst = [[0] for _ in range(3)]

Quick Math and Built-in Functions Recap

print(sum([1, 2, 3]))   # 6
print(min([4, 2, 1]))   # 1
print(max([4, 2, 1]))   # 4
print(sorted([7, 2, 9])) # [2, 7, 9]

Deleting elements:

x = 42
del x

Placeholders:

def future_function():
    pass

None represents “no value”:

def greet():
    print("Hello")

print(greet())  # Hello \n None

Summary

In this session, we explored how to:

  • Use tuples for immutable data structures.
  • Manipulate dictionaries effectively.
  • Build concise and readable loops with list comprehensions.
  • Understand mathematical functions and built-ins like abs(), divmod(), and math.sqrt().

Leave a Reply

Your email address will not be published. Required fields are marked *