Python Modules

Python Modules Tutorial

Introduction

Python, renowned for its simplicity and versatility, owes a significant part of its power to modules. Modules are an essential concept in Python programming, enabling developers to organize code, enhance reusability, and maintain a clean project structure. In this tutorial, we’ll delve into the world of Python modules, exploring their significance, creation, unique features, and diverse applications.

Importance of Modules

Modules serve as building blocks that encapsulate code, variables, and functions, making it easier to manage and scale projects. By grouping related functionalities together, modules facilitate code readability, reduce redundancy, and enable collaborative development. This modular approach enhances the maintainability and extensibility of Python applications.

Creating a Module

Creating a module is a straightforward process. To begin, save a collection of related functions and variables in a .py file. This file name becomes the module name. For instance, let’s create a simple module named math_operations:

				
					# math_operations.py
def add(a, b):
    return a + b

def subtract(a, b):
    return a - b

def multiply(a, b):
    return a * b

				
			

Features

Python modules offer a range of features that streamline development and optimize code organization:

  1. Namespace Isolation: Modules create separate namespaces, preventing naming conflicts between variables and functions.
  2. Reusability: Code encapsulated within modules can be easily reused in multiple projects.
  3. Modularity: Modules support a modular architecture, enhancing code separation and maintainability.
  4. Information Hiding: By controlling what is exposed in a module’s interface, you can encapsulate implementation details.
  5. Standard Library: Python’s standard library provides a plethora of pre-built modules, saving time and effort in coding common functionalities.

Different Python Modules

  1. Math Module: The math module offers a suite of mathematical functions. Let’s calculate the factorial of a number using the math module:
				
					import math
num = 5
factorial = math.factorial(num)
print(f"The factorial of {num} is {factorial}")

				
			
  1. Datetime Module: The datetime module simplifies date and time manipulation. Here’s an example of getting the current date and time:
				
					import datetime
current_datetime = datetime.datetime.now()
print(f"Current date and time: {current_datetime}")

				
			
  1. Random Module: The random module facilitates random number generation. Let’s generate a random integer between 1 and 100:
				
					import random
random_number = random.randint(1, 100)
print(f"Random number: {random_number}")

				
			
  1. JSON Module: The json module simplifies JSON encoding and decoding. Here, we’ll encode a Python dictionary as a JSON string:
				
					import json
data = {'name': 'John', 'age': 30, 'city': 'New York'}
json_string = json.dumps(data)
print(f"JSON representation: {json_string}")

				
			

Python Classes & Objects

Python Tutorial › Object-Oriented Python › Classes & Objects

Python Classes & Objects

IntermediateLesson 31 of 4714 min read8 runnable examples

A class is a blueprint, and an object is a thing built from that blueprint. Classes bundle data (attributes) with the functions that work on it (methods). Page objects in test automation, models in web apps and most libraries you use are built from classes.

In this lesson

  • Define a class and create objects
  • Use __init__ and self correctly
  • Class vs instance attributes
  • Special methods, classmethods and dataclasses

Define a class and create objects

Python
class Dog:    pass rex = Dog()bella = Dog()print(type(rex).__name__, rex is bella)

Output
Dog False

Each call to Dog() creates a new, separate object (an instance) of the class.

__init__ and self

__init__ runs automatically when an object is created. Use it to set the object’s starting attributes. self is the object being created; Python passes it for you.

Python
class Account:    def __init__(self, owner, balance=0):        self.owner = owner          # instance attribute        self.balance = balance acc1 = Account("Asha", 500)acc2 = Account("Ravi")print(acc1.owner, acc1.balance)print(acc2.owner, acc2.balance)

Output
Asha 500
Ravi 0
Note

self is just the conventional name for the first parameter. Every method needs it, because it is how the method reaches the object’s data.

Methods

Methods are functions defined inside a class. Call them on an object with a dot.

Python
class Account:    def __init__(self, owner, balance=0):        self.owner = owner        self.balance = balance     def deposit(self, amount):        if amount <= 0:            raise ValueError("Deposit must be positive")        self.balance += amount        return self.balance     def withdraw(self, amount):        if amount > self.balance:            print("Insufficient funds")            return self.balance        self.balance -= amount        return self.balance acc = Account("Asha", 100)print(acc.deposit(50))print(acc.withdraw(500))print(acc.withdraw(30))

Output
150
Insufficient funds
150
120

acc.deposit(50) is really Account.deposit(acc, 50): the object goes into self.

Class attributes vs instance attributes

An attribute set on the class is shared by all objects. One set on self belongs to a single object.

Python
class Employee:    company = "SQA Tools"          # class attribute: shared    count = 0     def __init__(self, name):        self.name = name           # instance attribute: per object        Employee.count += 1 a = Employee("Asha")b = Employee("Ravi")print(a.company, b.company, Employee.count)print(a.name, b.name)

Output
SQA Tools SQA Tools 2
Asha Ravi

__str__ and __repr__

Special methods (with double underscores) let your objects work with built-in functions. __str__ controls print(); __repr__ controls how the object looks in lists and the shell.

Python
class Product:    def __init__(self, name, price):        self.name = name        self.price = price     def __str__(self):        return f"{self.name} (Rs {self.price})"     def __repr__(self):        return f"Product({self.name!r}, {self.price})" p = Product("Mouse", 349)print(p)print([p, Product("Pen", 10)])

Output
Mouse (Rs 349)
[Product('Mouse', 349), Product('Pen', 10)]

Other useful special methods include __len__, __eq__ and __lt__:

Python
class Playlist:    def __init__(self, *songs):        self.songs = list(songs)     def __len__(self):        return len(self.songs)     def __eq__(self, other):        return self.songs == other.songs p1 = Playlist("a", "b")p2 = Playlist("a", "b")print(len(p1), p1 == p2, p1 is p2)

Output
2 True False

classmethod and staticmethod

  • A @classmethod receives the class (cls) instead of an object. It is often used as an alternative constructor.
  • A @staticmethod receives neither; it is a plain function grouped with the class.
Python
class Temperature:    def __init__(self, celsius):        self.celsius = celsius     @classmethod    def from_fahrenheit(cls, f):        return cls(round((f - 32) * 5 / 9, 1))     @staticmethod    def is_freezing(celsius):        return celsius <= 0 t = Temperature.from_fahrenheit(98.6)print(t.celsius, Temperature.is_freezing(t.celsius))

Output
37.0 False

Dataclasses

For classes that mainly hold data, @dataclass writes __init__, __repr__ and __eq__ for you:

Python
from dataclasses import dataclass, field @dataclassclass TestCase:    name: str    priority: int = 3    tags: list = field(default_factory=list) tc = TestCase("login works", 1, ["smoke"])print(tc)print(tc == TestCase("login works", 1, ["smoke"]))

Output
TestCase(name='login works', priority=1, tags=['smoke'])
True

Check your understanding

Predict the output

class Counter:    total = 0    def __init__(self):        self.mine = 0    def hit(self):        self.mine += 1        Counter.total += 1 a, b = Counter(), Counter()a.hit(); a.hit(); b.hit()print(a.mine, b.mine, Counter.total)

Quick quiz

1. What is self in a method?

2. When does __init__ run?

3. Which method controls what print(obj) shows?

4. What does a @classmethod receive as its first argument?

Exercise: rectangle class

Create a Rectangle class with width and height, methods area() and perimeter(), and a __str__ that prints like Rectangle 4x6.

Input

Rectangle(4, 6)
Expected output

Rectangle 4x6
Area: 24
Perimeter: 20
Hint 1

Store width and height on self in __init__.

Program Practice

48 Python OOP Programs

Every program has a step-by-step explanation, colour-coded code and its real output.

Start practising →

Related sets:All practice sets

Python classes and objects FAQ

What is the difference between a class and an object?

A class is the definition (the blueprint). An object is a concrete instance created from it, with its own attribute values.

Why do Python methods need self?

self is how a method accesses the object it was called on. Python passes the object automatically as the first argument.

What is __init__ in Python?

It is the initialiser that runs right after an object is created. It sets up the object’s attributes.

When should I use a dataclass?

When a class mainly stores data. @dataclass generates the boilerplate methods and keeps the class short and readable.

Python NumPy

Python Tutorial › Libraries & Databases › NumPy

Python NumPy

IntermediateLesson 45 of 4714 min read11 runnable examples

NumPy is the foundation of numerical Python. Its ndarray stores numbers in a compact block of memory and runs maths on whole arrays at once, which is far faster and shorter than looping over lists. Pandas, scikit-learn and Matplotlib are all built on it.

In this lesson
  • Create arrays and inspect their shape
  • Index, slice and filter with masks
  • Vectorised maths and broadcasting
  • Statistics along rows and columns

Install and import

Terminal
python -m pip install numpy
Python
import numpy as npprint(np.__version__.split(".")[0] >= "2")
Output
True

np is the standard alias; every NumPy example you find online uses it.

Create arrays

Python
import numpy as np a = np.array([3, 1, 4, 1, 5])print(a, a.dtype, a.shape) m = np.array([[1, 2, 3], [4, 5, 6]])print(m)print(m.shape, m.ndim, m.size)
Output
[3 1 4 1 5] int64 (5,)
[[1 2 3]
 [4 5 6]]
(2, 3) 2 6

Helper functions build common arrays:

Python
import numpy as np print(np.zeros(3), np.ones((2, 2), dtype=int).tolist())print(np.arange(0, 10, 2))print(np.linspace(0, 1, 5))print(np.eye(3, dtype=int))
Output
[0. 0. 0.] [[1, 1], [1, 1]]
[0 2 4 6 8]
[0.   0.25 0.5  0.75 1.  ]
[[1 0 0]
 [0 1 0]
 [0 0 1]]

Arrays vs lists

Maths on an array applies to every element. The same operator on a list does something else:

Python
import numpy as np prices = [100, 250, 80]print(prices * 2)                 # list: repeated arr = np.array(prices)print(arr * 2)                    # array: every element doubledprint(arr * 1.18)                 # add 18% tax to allprint(arr + np.array([1, 2, 3]))  # element-wise addition
Output
[100, 250, 80, 100, 250, 80]
[200 500 160]
[118.  295.   94.4]
[101 252  83]

Reshape

Python
import numpy as np a = np.arange(1, 13)grid = a.reshape(3, 4)print(grid)print(grid.T.shape)               # transpose: 4 x 3print(grid.flatten()[:5])
Output
[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]
(4, 3)
[1 2 3 4 5]

Indexing and slicing

For 2-D arrays, use [row, column]:

Python
import numpy as np g = np.arange(1, 13).reshape(3, 4)print(g[0, 0], g[2, -1])print(g[1])            # second rowprint(g[:, 1])         # second columnprint(g[0:2, 1:3])     # sub-grid
Output
1 12
[5 6 7 8]
[ 2  6 10]
[[2 3]
 [6 7]]

Boolean masks

A comparison gives an array of True/False values, which you can use to select elements:

Python
import numpy as np scores = np.array([45, 82, 67, 91, 38, 74])mask = scores >= 60print(mask)print(scores[mask])print(scores[(scores > 50) & (scores < 80)])   # use & and |, not and/orprint(np.where(scores >= 60, "pass", "fail"))
Output
[False  True  True  True False  True]
[82 67 91 74]
[67 74]
['fail' 'pass' 'pass' 'pass' 'fail' 'pass']

Statistics

Python
import numpy as np sales = np.array([[120, 90, 150],                  [80, 110, 95]])       # 2 stores x 3 monthsprint(sales.sum(), sales.mean().round(2))print(sales.sum(axis=0))                # per month (down the columns)print(sales.sum(axis=1))                # per store (across the rows)print(sales.max(), sales.argmax(), np.median(sales))
Output
645 107.5
[200 200 245]
[360 285]
150 2 102.5
Tip

axis=0 means “collapse the rows” (one result per column) and axis=1 means “collapse the columns” (one result per row).

Broadcasting

When shapes differ, NumPy stretches the smaller array to fit, as long as the dimensions are compatible:

Python
import numpy as np marks = np.array([[70, 80, 90],                  [60, 75, 85]])bonus = np.array([5, 0, 10])            # one bonus per subjectprint(marks + bonus)print(marks / marks.max(axis=1, keepdims=True))   # normalise each row
Output
[[ 75  80 100]
 [ 65  75  95]]
[[0.77777778 0.88888889 1.        ]
 [0.70588235 0.88235294 1.        ]]

Random numbers

Python
import numpy as np rng = np.random.default_rng(seed=42)print(rng.integers(1, 7, size=5))         # dice rollsprint(rng.random(3).round(3))print(rng.choice(["red", "green", "blue"], size=4))
Output
[1 5 4 3 3]
[0.697 0.094 0.976]
['blue' 'blue' 'blue' 'blue']

A fixed seed makes the results repeatable, which is useful for tests.

Why NumPy is fast

Python
import numpy as np, time n = 1_000_000numbers = list(range(n))arr = np.arange(n) t = time.perf_counter(); total_list = sum(x * x for x in numbers); list_time = time.perf_counter() - tt = time.perf_counter(); total_np = int((arr * arr).sum()); np_time = time.perf_counter() - t print(total_list == total_np)print("NumPy faster:", np_time < list_time)
Output
True
NumPy faster: True

Check your understanding

Predict the output

import numpy as npa = np.array([[1, 2], [3, 4]])print(a * a, a.sum(axis=0), a[a > 2])

Quick quiz

1. What is np.array([1, 2, 3]) * 2?

2. What does arr.shape return for a 3 x 4 array?

3. Which combines two conditions in a mask?

Exercise: class report

Marks of 4 students in 3 subjects are in a 4 x 3 array. Print each student’s total, each subject’s average, and how many marks are below 40.

Input
[[78, 65, 90], [35, 48, 52], [88, 92, 79], [40, 39, 61]]
Expected output
Totals: [233 135 259 140]
Subject averages: [60.25 61.   70.5 ]
Marks below 40: 2
Hint 1

sum(axis=1) for students, mean(axis=0) for subjects.

Program Practice

NumPy FAQ

What is NumPy used for?

Fast numerical computing: arrays, linear algebra, statistics and random numbers. It is the base for pandas, SciPy, scikit-learn and most data and ML libraries.

What is the difference between a Python list and a NumPy array?

A NumPy array holds items of one type in contiguous memory and supports element-wise maths. A list can mix types and its operators mean concatenation and repetition.

What does axis=0 mean in NumPy?

It means “along the rows”, so the result has one value per column. axis=1 gives one value per row.

Python Pandas

Python Tutorial › Libraries & Databases › Pandas

Python Pandas

IntermediateLesson 46 of 4715 min read12 runnable examples

pandas turns tables of data into DataFrames that you can filter, sort, group and summarise in a few lines. It reads CSV, Excel, JSON and SQL, which makes it the everyday tool for data analysis and for preparing test data.

In this lesson
  • Create Series and DataFrames
  • Read CSV files and inspect the data
  • Select, filter and sort rows
  • Handle missing values, group and merge

Install and import

Terminal
python -m pip install pandas
Python
import pandas as pdprint(int(pd.__version__.split(".")[0]) >= 2)
Output
True
Note

The examples were run with pandas 3. The in-browser Try it uses an older pandas, so a few outputs (such as column types) may print slightly differently there.

Series and DataFrame

A Series is one labelled column. A DataFrame is a table of Series that share an index.

Python
import pandas as pd scores = pd.Series([91, 78, 85], index=["Asha", "Ravi", "Meena"])print(scores)print(scores["Ravi"], scores.mean().round(2))
Output
Asha     91
Ravi     78
Meena    85
dtype: int64
78 84.67
Python
import pandas as pd df = pd.DataFrame({    "name": ["Asha", "Ravi", "Meena", "John", "Sara"],    "dept": ["QA", "Dev", "QA", "Ops", "Dev"],    "salary": [52000, 61000, 48000, 55000, 67000],    "years": [4, 6, 2, 5, 8],})print(df)print(df.shape)
Output
    name dept  salary  years
0   Asha   QA   52000      4
1   Ravi  Dev   61000      6
2  Meena   QA   48000      2
3   John  Ops   55000      5
4   Sara  Dev   67000      8
(5, 4)

Read a CSV file

Python
import pandas as pd with open("orders.csv", "w") as f:    f.write("order_id,city,amount,status\n101,Pune,1200,paid\n102,Delhi,450,pending\n"            "103,Pune,980,paid\n104,Mumbai,,cancelled\n105,Delhi,2300,paid\n") orders = pd.read_csv("orders.csv")print(orders.head(3))print(orders.dtypes["amount"], len(orders))
Output
   order_id   city  amount   status
0       101   Pune  1200.0     paid
1       102  Delhi   450.0  pending
2       103   Pune   980.0     paid
float64 5

Quick ways to inspect a new dataset:

Python
import pandas as pd orders = pd.read_csv("orders.csv")print(orders.columns.tolist())print(orders["amount"].describe().round(1).to_dict())print(orders["city"].value_counts().to_dict())
Output
['order_id', 'city', 'amount', 'status']
{'count': 4.0, 'mean': 1232.5, 'std': 778.2, 'min': 450.0, '25%': 847.5, '50%': 1090.0, '75%': 1475.0, 'max': 2300.0}
{'Pune': 2, 'Delhi': 2, 'Mumbai': 1}

Select columns and rows

Python
import pandas as pd df = pd.DataFrame({"name": ["Asha", "Ravi", "Meena"], "dept": ["QA", "Dev", "QA"], "salary": [52000, 61000, 48000]}) print(df["name"].tolist())             # one columnprint(df[["name", "salary"]])          # several columnsprint(df.loc[1, "name"])               # by labelprint(df.iloc[0].to_dict())            # by position
Output
['Asha', 'Ravi', 'Meena']
    name  salary
0   Asha   52000
1   Ravi   61000
2  Meena   48000
Ravi
{'name': 'Asha', 'dept': 'QA', 'salary': 52000}

Filter rows

Python
import pandas as pd df = pd.DataFrame({    "name": ["Asha", "Ravi", "Meena", "John", "Sara"],    "dept": ["QA", "Dev", "QA", "Ops", "Dev"],    "salary": [52000, 61000, 48000, 55000, 67000],})print(df[df["salary"] > 55000])print(df[(df["dept"] == "QA") & (df["salary"] > 50000)]["name"].tolist())print(df[df["dept"].isin(["Dev", "Ops"])].shape[0])print(df.query("salary < 50000")["name"].tolist())
Output
   name dept  salary
1  Ravi  Dev   61000
4  Sara  Dev   67000
['Asha']
3
['Meena']

Sort and add columns

Python
import pandas as pd df = pd.DataFrame({"name": ["Asha", "Ravi", "Meena"], "salary": [52000, 61000, 48000], "years": [4, 6, 2]})df["bonus"] = df["salary"] * 0.1df["level"] = df["years"].apply(lambda y: "senior" if y >= 5 else "junior")print(df.sort_values("salary", ascending=False))
Output
    name  salary  years   bonus   level
1   Ravi   61000      6  6100.0  senior
0   Asha   52000      4  5200.0  junior
2  Meena   48000      2  4800.0  junior

Missing data

Python
import pandas as pd orders = pd.read_csv("orders.csv")print(orders["amount"].isna().sum())print(orders.dropna(subset=["amount"]).shape)filled = orders.fillna({"amount": 0})print(filled["amount"].tolist())
Output
1
(4, 4)
[1200.0, 450.0, 980.0, 0.0, 2300.0]

Group and aggregate

groupby splits the rows into groups, applies a calculation to each, and combines the results:

Python
import pandas as pd orders = pd.read_csv("orders.csv")paid = orders[orders["status"] == "paid"]print(paid.groupby("city")["amount"].sum())print(orders.groupby("status").size().to_dict())print(paid.groupby("city")["amount"].agg(["count", "mean"]))
Output
city
Delhi    2300.0
Pune     2180.0
Name: amount, dtype: float64
{'cancelled': 1, 'paid': 3, 'pending': 1}
       count    mean
city                
Delhi      1  2300.0
Pune       2  1090.0

Merge two tables

Python
import pandas as pd users = pd.DataFrame({"user_id": [1, 2, 3], "name": ["Asha", "Ravi", "Meena"]})orders = pd.DataFrame({"order_id": [10, 11, 12, 13], "user_id": [1, 1, 3, 4], "amount": [500, 250, 900, 100]}) joined = orders.merge(users, on="user_id", how="left")print(joined)print(joined.groupby("name")["amount"].sum().to_dict())
Output
   order_id  user_id  amount   name
0        10        1     500   Asha
1        11        1     250   Asha
2        12        3     900  Meena
3        13        4     100    NaN
{'Asha': 750, 'Meena': 900}

A left merge keeps every order; user 4 has no match, so name is missing (NaN) for that row.

Save results

Python
import pandas as pd orders = pd.read_csv("orders.csv")summary = orders.groupby("city", as_index=False)["amount"].sum()summary.to_csv("city_totals.csv", index=False)print(open("city_totals.csv").read().strip())
Output
city,amount
Delhi,2750.0
Mumbai,0.0
Pune,2180.0

Check your understanding

Predict the output

import pandas as pddf = pd.DataFrame({"x": [1, 2, 3, 4], "g": ["a", "b", "a", "b"]})print(df[df["x"] > 1]["x"].sum(), df.groupby("g")["x"].sum().to_dict())

Quick quiz

1. Which reads a CSV file into a DataFrame?

2. What is the difference between loc and iloc?

3. How do you count missing values in a column?

Exercise: department report

For each department, print the number of employees and the average salary, sorted by average salary, highest first.

Input
the employee DataFrame from the Series and DataFrame section
Expected output
      count     mean
dept                
Dev       2  64000.0
Ops       1  55000.0
QA        2  50000.0
Hint 1

groupby("dept")["salary"].agg(["count", "mean"]), then sort_values("mean", ascending=False).

Program Practice

95 Python Pandas Programs

Every program has a step-by-step explanation, colour-coded code and its real output.

Start practising →
Related sets:All practice sets

Pandas FAQ

What is pandas used for in Python?

Loading, cleaning, transforming and summarising tabular data from CSV, Excel, JSON and SQL sources.

What is the difference between a Series and a DataFrame?

A Series is a single labelled column. A DataFrame is a two-dimensional table made of several Series that share an index.

How do I filter rows in pandas?

Use a boolean condition inside brackets: df[df["salary"] > 50000]. Combine conditions with & and | and wrap each one in brackets.

How do I handle missing values in pandas?

Find them with isna(), remove them with dropna(), or replace them with fillna().

Python File Handling

Python Tutorial › File Handling › File Handling

Python File Handling

BeginnerLesson 41 of 4712 min read11 runnable examples

Programs save results, read test data and process logs, and all of that means working with files. Python’s built-in open() function plus a with block is all you need for text files.

In this lesson
  • Open files safely with with
  • Choose the right file mode
  • Read a whole file, a line, or all lines
  • Write, append and process files line by line

Write a file

open(path, mode) returns a file object. Mode "w" creates the file (or empties it if it exists). The with block closes the file automatically, even if an error happens.

Python
with open("notes.txt", "w", encoding="utf-8") as f:    f.write("Python file handling\n")    f.write("Line two\n")    f.writelines(["Line three\n", "Line four\n"]) print("written")
Output
written
Tip

Always pass encoding="utf-8" for text files. Without it, Python uses the operating system’s default encoding, which differs between Windows and Linux.

Read a whole file

Python
with open("notes.txt", encoding="utf-8") as f:    content = f.read() print(repr(content[:25]))print(len(content.splitlines()), "lines")
Output
'Python file handling\nLine'
4 lines

Read line by line

A file object is iterable: a for loop gives one line at a time, which works for files of any size.

Python
with open("notes.txt", encoding="utf-8") as f:    for number, line in enumerate(f, start=1):        print(number, line.rstrip("\n"))
Output
1 Python file handling
2 Line two
3 Line three
4 Line four

readline() reads the next line; readlines() returns a list of all lines (keeping the \n):

Python
with open("notes.txt", encoding="utf-8") as f:    first = f.readline()    rest = f.readlines() print(repr(first))print(rest)
Output
'Python file handling\n'
['Line two\n', 'Line three\n', 'Line four\n']

File modes

ModeMeaningIf the file existsIf it does not
"r"read (default)read from the startFileNotFoundError
"w"writeemptied firstcreated
"a"appendwrite at the endcreated
"x"exclusive createFileExistsErrorcreated
"r+"read and writefrom the startFileNotFoundError
add "b"binary, e.g. "rb"bytes instead of str

Append to a file

Python
with open("notes.txt", "a", encoding="utf-8") as f:    f.write("Appended line\n") with open("notes.txt", encoding="utf-8") as f:    print(f.read().splitlines()[-2:])
Output
['Line four', 'Appended line']

Handle a missing file

Python
with open("does_not_exist.txt", encoding="utf-8") as f:    print(f.read())
Output
Traceback (most recent call last):
  File "main.py", line 1, in <module>
    with open("does_not_exist.txt", encoding="utf-8") as f:
         ~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: 'does_not_exist.txt'

Check first, or catch the error:

Python
from pathlib import Path path = Path("does_not_exist.txt")if path.exists():    print(path.read_text(encoding="utf-8"))else:    print(f"{path} not found, using defaults") try:    open("does_not_exist.txt", encoding="utf-8")except FileNotFoundError as e:    print("Caught:", e.strerror)
Output
does_not_exist.txt not found, using defaults
Caught: No such file or directory

Process a log file

A typical job: read a log, count errors and write a summary.

Python
log = """2026-11-02 09:00 INFO start2026-11-02 09:01 ERROR db timeout2026-11-02 09:02 INFO retry2026-11-02 09:03 ERROR db timeout2026-11-02 09:04 WARN slow response"""with open("app.log", "w", encoding="utf-8") as f:    f.write(log) counts = {}errors = []with open("app.log", encoding="utf-8") as f:    for line in f:        level = line.split()[2]        counts[level] = counts.get(level, 0) + 1        if level == "ERROR":            errors.append(line.split(maxsplit=3)[3].strip()) with open("summary.txt", "w", encoding="utf-8") as out:    for level, n in sorted(counts.items()):        out.write(f"{level}: {n}\n") print(open("summary.txt", encoding="utf-8").read().strip())print(set(errors))
Output
ERROR: 2
INFO: 2
WARN: 1
{'db timeout'}

Read and write several files

Python
with open("notes.txt", encoding="utf-8") as src, open("upper.txt", "w", encoding="utf-8") as dst:    for line in src:        dst.write(line.upper()) print(open("upper.txt", encoding="utf-8").readline().strip())
Output
PYTHON FILE HANDLING

Binary files

Images, PDFs and zip files are binary. Open them with "rb" / "wb" and you get bytes:

Python
data = bytes([137, 80, 78, 71])          # the first bytes of every PNG filewith open("sample.bin", "wb") as f:    f.write(data) with open("sample.bin", "rb") as f:    head = f.read()print(head, len(head))
Output
b'\x89PNG' 4

seek and tell

Python
with open("notes.txt", encoding="utf-8") as f:    print(f.read(6))    print(f.tell())        # current position    f.seek(0)              # back to the start    print(f.readline().strip())
Output
Python
6
Python file handling

Check your understanding

Predict the output

with open("t.txt", "w") as f:    f.write("a\nb\n")with open("t.txt", "w") as f:    f.write("c\n")print(open("t.txt").read().split())

Quick quiz

1. What does mode “w” do to an existing file?

2. Why use with open(...) as f:?

3. Which reads one line at a time without loading the whole file?

Exercise: word statistics

Write a short text to story.txt, then read it back and print the number of lines, words and characters, and the longest word.

Input
"Python reads files easily\nAnd writes them too\n"
Expected output
2 8 46 Python
Hint 1

Count lines while looping; len(line.split()) counts words.

Program Practice

Python file handling FAQ

How do I read a file line by line in Python?

with open(path, encoding="utf-8") as f: then for line in f:. Use line.rstrip("\n") to drop the newline.

What is the difference between write() and writelines()?

write() writes one string. writelines() writes every string from a list or other iterable; neither adds newlines for you.

How do I check if a file exists before opening it?

Use os.path.exists(path) or Path(path).exists(), or open it inside try and catch FileNotFoundError.

Do I need to close a file in Python?

Not when you use with, which closes it automatically. Otherwise call f.close() yourself.

Python Lambda Function

Python Lambda Function Tutorial

Python Lambda Functions ( Anonymous function )

Anonymous functions in Python, also known as lambda functions, allow you to create small, one-line functions without explicitly defining a function using the `def` keyword.

Syntax: `lambda arguments: expression`

The `lambda` keyword is used to define a lambda function. It is followed by the arguments (comma-separated) and a colon (:), then the expression that is evaluated and returned as the function’s result. Here is an example:

				
					# Creating a lambda function to add two numbers
add_numbers = lambda x, y: x + y

# Calling the lambda function
result = add_numbers(10, 15)
print(result)  # Output: 25

				
			

In this example, we define a lambda function `add_numbers` that takes two arguments, `x` and `y`. The function adds these two numbers together using the `+` operator and returns the result. We then call the lambda function by providing the arguments `10` and `15`, and store the returned value in the `result` variable.

Lambda functions are commonly used when you need a simple, one-line function and don’t want to define a separate named function. They are often used in combination with built-in functions like `map()`, `filter()`, and `reduce()` to perform operations on iterables in a concise and readable manner.

Features of Python Lambda Functions:

  1. Anonymity: Lambda functions do not have a name, making them useful for short, simple operations where defining a separate function using def is not necessary.
  2. Compactness: Lambda functions are typically concise and can be defined in a single line.
  3. Single Expression: Lambda functions are limited to a single expression, which means they cannot contain multiple statements or complex logic.
  4. Functional Programming: Lambda functions are commonly used in functional programming to pass behavior as arguments to higher-order functions like map, filter, and reduce.

Difference between Built-in functions and Lambda functions (also known as Anonymous functions)

In Python, the main difference between built-in functions and anonymous functions (also known as lambda functions) lies in their structure, creation, and usage.

Built-in Functions:

Built-in functions in Python are pre-defined functions that are provided by the Python language itself. They are readily available for use without any additional coding or import statements. These functions cover a wide range of tasks and operations, such as mathematical calculations, string manipulations, list operations, file I/O, etc. They are named and can be used repeatedly throughout the code. Here’s an example of using a built-in function to find the length of a list:

				
					# Using the built-in function len() to find the length of a list
numbers = [1, 2, 3, 4, 5]
length = len(numbers)
print(length)  # Output: 5

				
			

In this example, the len() function is a built-in function that returns the number of elements in the list numbers.

Lambda Functions (Anonymous Functions):

Lambda functions are a special type of function in Python that allows you to create small, one-line functions without explicitly defining them using the def keyword. Lambda functions are typically used for simple, one-time tasks and are often used in conjunction with higher-order functions like map(), filter(), and reduce().

Lambda functions have the following structure: lambda arguments: expression

The lambda function takes a set of arguments, performs the specified expression on those arguments, and returns the result of the expression. Here’s an example of a lambda function that calculates the square of a number:

				
					# Using a lambda function to calculate the square of a number
square = lambda x: x**2
result = square(5)
print(result)  # Output: 25

				
			

In this example, we create a lambda function that takes an argument x, calculates the square using the expression x**2, and then we call the lambda function with square(5) to calculate the square of 5.

Key Differences:

  1. Structure and Definition: Built-in functions are predefined and come with Python, whereas lambda functions are created on-the-fly and are not explicitly defined using the def keyword.
  2. Usage and Complexity: Built-in functions are used for a wide range of tasks and can be complex with multiple parameters, whereas lambda functions are typically used for simple operations with one or few parameters.
  3. Naming: Built-in functions have names, and you can call them using their names whenever needed. Lambda functions, on the other hand, do not have names and are often used as temporary, inline functions.
  4. Return Statement: Built-in functions return their results as any other function, using the return statement. Lambda functions automatically return the value of the expression without using the return statement.
  5. Use Cases: Built-in functions are ideal for general-purpose and reusable tasks, while lambda functions are more suited for immediate, short-term, and one-time uses.

Python Built In Functions

Python Built In Functions

Introduction

Python is a powerful and versatile programming language that comes with a rich set of built-in functions. These functions are pre-defined and readily available, making it easier for developers to accomplish various tasks without having to write the code from scratch. In this tutorial, we will explore what built-in functions are in Python, provide examples of some commonly used built-in functions, and explain the difference between built-in functions and user-defined functions.

What are Built-in Functions in Python?

Built-in functions are functions that are built into the Python programming language. They are always available and do not require any additional installations or imports. These functions are designed to perform common tasks and operations on different types of data. Python provides a wide range of built-in functions, which can be broadly categorized into the following types:

  1. Mathematical Functions: These functions perform various mathematical operations such as calculating absolute values, rounding numbers, finding maximum and minimum values, and more.
  2. String Functions: String functions handle operations on strings, such as concatenation, case conversions, finding substrings, and more.
  3. List Functions: List functions deal with operations on lists, including sorting, adding elements, removing elements, and more.
  4. Dictionary Functions: These functions work with dictionaries, enabling operations like accessing keys, values, merging dictionaries, etc.
  5. File Input/Output Functions: File-related functions help in reading from and writing to files.
  6. Type Conversion Functions: Type conversion functions allow you to convert data from one type to another, such as converting integers to strings or vice versa.
  7. Other Utility Functions: Python also provides several other utility functions for tasks like input/output, formatting, etc.

Now, let’s explore some examples of commonly used built-in functions in Python.

Examples of Python Built-in Functions:

  1. Mathematical Functions:
				
					# Absolute value
abs_result = abs(-10)	
print(abs_result)  # Output: 10

# Rounding
round_result = round(3.14159, 2)
print(round_result)  # Output: 3.14

# Maximum and Minimum
max_result = max(5, 9, 3, 7)
print(max_result)  # Output: 9

min_result = min(5, 9, 3, 7)
print(min_result)  # Output: 3

				
			
  1. String Functions:
				
					# Concatenation
str1 = "Hello"
str2 = "World"
concatenated_str = str1 + " " + str2
print(concatenated_str)  # Output: "Hello World"

# Upper and Lower case
text = "Python is Amazing"
uppercase_text = text.upper()
lowercase_text = text.lower()
print(uppercase_text)  # Output: "PYTHON IS AMAZING"
print(lowercase_text)  # Output: "python is amazing"

# Finding substring
sentence = "Python programming is fun"
substring = "programming"
index = sentence.find(substring)
print(index)  # Output: 7

				
			
  1. List Functions:
				
					# Sorting
numbers = [5, 2, 8, 1, 3]
numbers.sort()
print(numbers)  # Output: [1, 2, 3, 5, 8]

# Appending elements
fruits = ["apple", "banana"]
fruits.append("orange")
print(fruits)  # Output: ['apple', 'banana', 'orange']

# Removing elements
fruits.remove("banana")
print(fruits)  # Output: ['apple', 'orange']

				
			
  1. Dictionary Functions:
				
					# Accessing keys and values
student_scores = {"Alice": 85, "Bob": 92, "Charlie": 78}
keys = student_scores.keys()
values = student_scores.values()
print(keys)  # Output: dict_keys(['Alice', 'Bob', 'Charlie'])
print(values)  # Output: dict_values([85, 92, 78])

# Merging dictionaries
more_scores = {"David": 88, "Eva": 95}
student_scores.update(more_scores)
print(student_scores)
# Output: {'Alice': 85, 'Bob': 92, 'Charlie': 78, 'David': 88, 'Eva': 95}

				
			
  1. File Input/Output Functions:
				
					# Writing to a file
with open("example.txt", "w") as file:
    file.write("Hello, this is an example file.")

# Reading from a file
with open("example.txt", "r") as file:
    content = file.read()
print(content)  # Output: "Hello, this is an example file."

				
			

Difference Between Built-in Functions and User-defined Functions:

The primary difference between built-in functions and user-defined functions lies in their origin and availability. Built-in functions are provided by the Python language itself and are readily available for use without any additional code. On the other hand, user-defined functions are created by the developers themselves to perform specific tasks and are not available in the language by default. Here’s an example to illustrate the difference:

User-defined Function:

				
					def square(x):
    return x ** 2

result = square(5)
print(result)  # Output: 25

				
			

Built-in Function:

				
					num_list = [2, 4, 6, 8, 10]
sum_result = sum(num_list)
print(sum_result)  # Output: 30

				
			

In the user-defined function example, we define a function called “square” that takes a parameter “x” and returns its square. In the built-in function example, we use the “sum” function, which is already provided by Python, to calculate the sum of the elements in the list.

Difference between Built-in functions and anonymous functions (also known as lambda functions)

In Python, the main difference between built-in functions and anonymous functions (also known as lambda functions) lies in their structure, creation, and usage.

Built-in Functions:

Built-in functions in Python are pre-defined functions that are provided by the Python language itself. They are readily available for use without any additional coding or import statements. These functions cover a wide range of tasks and operations, such as mathematical calculations, string manipulations, list operations, file I/O, etc. They are named and can be used repeatedly throughout the code. Here’s an example of using a built-in function to find the length of a list:

				
					# Using the built-in function len() to find the length of a list
numbers = [1, 2, 3, 4, 5]
length = len(numbers)
print(length)  # Output: 5

				
			

In this example, the len() function is a built-in function that returns the number of elements in the list numbers.

Anonymous Functions (Lambda Functions):

Lambda functions are a special type of function in Python that allows you to create small, one-line functions without explicitly defining them using the def keyword. Lambda functions are typically used for simple, one-time tasks and are often used in conjunction with higher-order functions like map(), filter(), and reduce(). Lambda functions have the following structure: lambda arguments: expression

The lambda function takes a set of arguments, performs the specified expression on those arguments, and returns the result of the expression. Here’s an example of a lambda function that calculates the square of a number:

				
					# Using a lambda function to calculate the square of a number
square = lambda x: x**2
result = square(5)
print(result)  # Output: 25

				
			

In this example, we create a lambda function that takes an argument x, calculates the square using the expression x**2, and then we call the lambda function with square(5) to calculate the square of 5.

Key Differences:

  1. Structure and Definition: Built-in functions are predefined and come with Python, whereas lambda functions are created on-the-fly and are not explicitly defined using the def keyword.
  2. Usage and Complexity: Built-in functions are used for a wide range of tasks and can be complex with multiple parameters, whereas lambda functions are typically used for simple operations with one or few parameters.
  3. Naming: Built-in functions have names, and you can call them using their names whenever needed. Lambda functions, on the other hand, do not have names and are often used as temporary, inline functions.
  4. Return Statement: Built-in functions return their results as any other function, using the return statement. Lambda functions automatically return the value of the expression without using the return statement.
  5. Use Cases: Built-in functions are ideal for general-purpose and reusable tasks, while lambda functions are more suited for immediate, short-term, and one-time uses.

Python List vs Tuple

Python Tutorial › Data Structures › List vs Tuple

Python List vs Tuple

BeginnerLesson 21 of 477 min read6 runnable examples

Lists and tuples both store ordered sequences, and both support indexing, slicing and loops. The difference that matters is that a list can change and a tuple cannot. That one difference decides which to use.

In this lesson

  • The key differences at a glance
  • Memory and speed compared
  • Why tuples can be dict keys
  • A simple rule for choosing

Differences at a glance

List Tuple
Syntax [1, 2, 3] (1, 2, 3)
Mutable Yes: add, remove, change items No
Methods Many: append, remove, sort… Two: count, index
Can be a dict key / set item No Yes, if its items are hashable
Memory More Less
Typical use A collection that grows or changes A fixed record of values

Mutability in practice

Python
cart = ["pen", "book"]cart.append("bag")cart[0] = "pencil"print(cart) location = (18.52, 73.86)print(hasattr(location, "append"))

Output
['pencil', 'book', 'bag']
False

Memory and speed

A tuple uses less memory than a list with the same items, because a list keeps spare room so it can grow.

Python
import sys items_list = [1, 2, 3, 4, 5]items_tuple = (1, 2, 3, 4, 5)print(sys.getsizeof(items_list), sys.getsizeof(items_tuple))

Output
104 88

Creating a tuple of constants is also faster, because Python can build it once when the code is compiled:

Python
import timeit print(timeit.timeit("[1, 2, 3, 4, 5]", number=1_000_000) > timeit.timeit("(1, 2, 3, 4, 5)", number=1_000_000))

Output
True
Note

The exact sizes and timings depend on your Python version and computer. The direction does not: tuples are smaller and faster to create.

Hashability: tuples as keys

Only immutable objects can be dictionary keys or set members.

Python
visited = {(0, 0), (0, 1), (1, 1)}print((0, 1) in visited) grid = {(2, 3): "wall", (4, 1): "door"}print(grid[(4, 1)])

Output
True
door
Python
visited = {[0, 0], [0, 1]}

Output
Traceback (most recent call last):
  File "main.py", line 1, in <module>
    visited = {[0, 0], [0, 1]}
              ^^^^^^^^^^^^^^^^
TypeError: cannot use 'list' as a set element (unhashable type: 'list')

Converting between them

Python
t = (3, 1, 2)lst = list(t)lst.sort()t = tuple(lst)print(t)

Output
(1, 2, 3)

Which should you use?

  • Use a list when the collection will change: items are added, removed or sorted, such as a shopping cart or a queue of test cases.
  • Use a tuple when the values belong together and should not change, such as (latitude, longitude), an RGB colour, a function returning several values, or a dictionary key.

Check your understanding

Quick quiz

1. Which can be used as a dictionary key?

2. Which uses less memory for the same five numbers?

3. You need to store an employee’s (id, name, joining date) record that never changes. Which fits best?

Program Practice

List vs tuple FAQ

Is a tuple faster than a list in Python?

Creating and iterating over a tuple is slightly faster and it uses less memory. The difference rarely matters; choose based on whether the data should change.

Why use a tuple instead of a list?

To signal that the data is fixed, to protect it from accidental changes, to use it as a dictionary key or set member, and to save a little memory.

Can a tuple contain a list?

Yes. The tuple cannot be changed, but the list inside it can. Such a tuple is not hashable, so it cannot be a dict key.

Python Functions

Python Tutorial › Functions › Functions

Python Functions

BeginnerLesson 24 of 4714 min read11 runnable examples

A function is a named block of code that you can run whenever you need it. Functions remove repetition, give a name to an idea, and make code easy to test. Every practice program becomes cleaner once it is wrapped in a function.

In this lesson
  • Define and call functions
  • Pass positional, keyword and default arguments
  • Return one or several values
  • Accept any number of arguments with *args and **kwargs

Define and call a function

def starts a function, followed by its name, brackets and a colon. The indented block is the body. Nothing runs until you call the function.

Python
def greet():    print("Hello from a function") greet()greet()
Output
Hello from a function
Hello from a function

Parameters and arguments

Parameters are the names in the definition; arguments are the values you pass in the call.

Python
def greet(name, course):    print(f"Hi {name}, welcome to {course}") greet("Asha", "Python")greet(course="Playwright", name="Ravi")     # keyword arguments: any order
Output
Hi Asha, welcome to Python
Hi Ravi, welcome to Playwright

Return a value

return sends a value back to the caller and ends the function. A function without return gives back None.

Python
def area(width, height):    return width * height def show(x):    print("value:", x) a = area(3, 4)print(a, area(5, 5) + 1)print(show(7))
Output
12 26
value: 7
None

Return several values as a tuple and unpack them:

Python
def stats(numbers):    return min(numbers), max(numbers), sum(numbers) / len(numbers) low, high, avg = stats([4, 8, 15, 16, 23, 42])print(low, high, round(avg, 2))
Output
4 42 18.0
Tip

Prefer functions that return a result over functions that print it. A returned value can be tested, stored or printed later; printed text is gone.

Default arguments

A default value is used when the caller leaves the argument out. Parameters with defaults must come after those without.

Python
def connect(host, port=443, secure=True):    scheme = "https" if secure else "http"    return f"{scheme}://{host}:{port}" print(connect("sqatools.in"))print(connect("localhost", 8080, secure=False))
Output
https://sqatools.in:443
http://localhost:8080
Watch out

Never use a mutable value such as [] as a default. It is created once, when the function is defined, and shared by every call:

Python
def add_item(item, basket=[]):          # bug    basket.append(item)    return basket print(add_item("pen"))print(add_item("book"))                 # the old pen is still there def add_item_fixed(item, basket=None):  # fix    if basket is None:        basket = []    basket.append(item)    return basket print(add_item_fixed("pen"), add_item_fixed("book"))
Output
['pen']
['pen', 'book']
['pen'] ['book']

*args: any number of positional arguments

A parameter with one * collects extra positional arguments into a tuple.

Python
def total(*prices):    print(type(prices).__name__, prices)    return sum(prices) print(total(10, 20, 30))print(total())
Output
tuple (10, 20, 30)
60
tuple ()
0

**kwargs: any number of keyword arguments

Two ** collect extra keyword arguments into a dictionary.

Python
def build_url(base, **params):    query = "&".join(f"{k}={v}" for k, v in params.items())    return f"{base}?{query}" if query else base print(build_url("https://api.example.com/users", page=2, limit=50))print(build_url("https://api.example.com/users"))
Output
https://api.example.com/users?page=2&limit=50
https://api.example.com/users

Unpack arguments in a call

and * also work the other way: they spread a list or dict into separate arguments.

Python
def describe(name, role, city):    return f"{name} ({role}) from {city}" row = ["Meena", "tester", "Pune"]info = {"name": "Ravi", "role": "dev", "city": "Delhi"}print(describe(*row))print(describe(**info))
Output
Meena (tester) from Pune
Ravi (dev) from Delhi

Docstrings and type hints

Python
def discount(price: float, percent: float = 10) -> float:    """Return the price after taking off `percent` per cent."""    return round(price * (1 - percent / 100), 2) print(discount(499.0))print(discount.__doc__)
Output
449.1
Return the price after taking off `percent` per cent.

Type hints (price: float, -> float) document what the function expects. Python does not enforce them, but IDEs and tools such as mypy use them to catch mistakes.

Functions are objects

A function can be stored in a variable, put in a list, or passed to another function:

Python
def shout(text):    return text.upper() + "!" def whisper(text):    return text.lower() + "..." for style in [shout, whisper]:    print(style.__name__, "->", style("Hello")) print(sorted(["banana", "fig", "apple"], key=len))
Output
shout -> HELLO!
whisper -> hello...
['fig', 'apple', 'banana']

Check your understanding

Predict the output

def f(a, b=2, *rest, **opts):    return a, b, rest, opts print(f(1))print(f(1, 5, 6, 7, debug=True))

Quick quiz

1. What does a function return if it has no return statement?

2. Which definition is valid?

3. Inside def f(*args), what type is args?

4. Why is def f(items=[]) a problem?

Exercise: is it a palindrome?

Write is_palindrome(text) that ignores case and spaces, and returns True or False.

Input
"Never odd or even", "Python"
Expected output
Never odd or even -> True
Python -> False
Hint 1

Clean the text first: "".join(text.lower().split()).

Hint 2

Compare the cleaned text with its reverse [::-1].

Program Practice

Python functions FAQ

What is the difference between a parameter and an argument?

A parameter is the name in the function definition (def greet(name)). An argument is the value passed in a call (greet("Asha")).

What are *args and **kwargs in Python?

args collects extra positional arguments into a tuple; kwargs collects extra keyword arguments into a dict. The names are conventions; the and do the work.

Can a Python function return multiple values?

Yes. return a, b returns a tuple, which the caller can unpack: x, y = f().

What is the difference between print and return in a function?

print shows text on the screen. return hands a value back to the caller so it can be used in further code.

Python Dictionaries

Python Tutorial › Data Structures › Dictionaries

Python Dictionaries

BeginnerLesson 23 of 4713 min read10 runnable examples

A dictionary stores data as key-value pairs, so you can look a value up by a meaningful key instead of a position. Dictionaries model JSON, configuration, database rows and counters, which makes them one of the most used types in Python.

In this lesson
  • Create dictionaries and read values safely
  • Add, update and delete keys
  • Loop over keys, values and items
  • Work with nested dicts and merging

Create a dictionary

Write key: value pairs inside curly braces. Keys are usually strings, but any immutable value works.

Python
user = {"name": "Asha", "role": "tester", "years": 4}print(user)print(len(user)) ports = dict(http=80, https=443)       # dict() with keyword argumentsprint(ports)
Output
{'name': 'Asha', 'role': 'tester', 'years': 4}
3
{'http': 80, 'https': 443}

Since Python 3.7, dictionaries keep the order in which keys were inserted.

Read values

Use square brackets with the key. A missing key raises KeyError, so use get() when a key may be absent.

Python
user = {"name": "Asha", "role": "tester"}print(user["name"])print(user.get("email"))                    # None instead of an errorprint(user.get("email", "not provided"))    # with a defaultprint("role" in user)                       # checks keys
Output
Asha
None
not provided
True
Python
user = {"name": "Asha"}print(user["email"])
Output
Traceback (most recent call last):
  File "main.py", line 2, in <module>
    print(user["email"])
          ~~~~^^^^^^^^^
KeyError: 'email'

Add, change and delete

Python
config = {"browser": "chromium", "headless": True} config["timeout"] = 30          # add a new keyconfig["browser"] = "firefox"   # replace an existing valueconfig.update({"retries": 2, "headless": False})print(config) removed = config.pop("retries")  # remove and returndel config["timeout"]           # removeprint(removed, config)
Output
{'browser': 'firefox', 'headless': False, 'timeout': 30, 'retries': 2}
2 {'browser': 'firefox', 'headless': False}

setdefault() returns a key’s value, adding it with a default first if it is missing:

Python
groups = {}for name, team in [("asha", "qa"), ("ravi", "dev"), ("meena", "qa")]:    groups.setdefault(team, []).append(name)print(groups)
Output
{'qa': ['asha', 'meena'], 'dev': ['ravi']}

Loop over a dictionary

Python
stock = {"pen": 40, "notebook": 0, "bag": 7} for item in stock:                  # keys    print(item, end=" ")print() print(list(stock.values())) for item, qty in stock.items():     # key and value together    if qty == 0:        print(item, "is out of stock")
Output
pen notebook bag 
[40, 0, 7]
notebook is out of stock

Count things with a dict

Counting is the classic dictionary job:

Python
text = "the quick brown fox jumps over the lazy dog the end"counts = {}for word in text.split():    counts[word] = counts.get(word, 0) + 1 print(counts["the"])top = max(counts, key=counts.get)print(top, counts[top])
Output
3
the 3
Tip

collections.Counter does this in one line: Counter(text.split()).most_common(1). See the Collections lesson.

Nested dictionaries

Values can be lists or other dictionaries, which is exactly the shape of JSON data.

Python
response = {    "status": 200,    "data": {        "user": {"id": 7, "name": "Ravi"},        "roles": ["admin", "tester"],    },}print(response["data"]["user"]["name"])print(response["data"]["roles"][-1])print(response.get("error", {}).get("message", "no error"))
Output
Ravi
tester
no error

Merge dictionaries

Python
defaults = {"browser": "chromium", "headless": True, "timeout": 30}overrides = {"headless": False} settings = defaults | overrides      # Python 3.9+print(settings)print({**defaults, **overrides} == settings)
Output
{'browser': 'chromium', 'headless': False, 'timeout': 30}
True

When both have the same key, the value from the right-hand dict wins.

Dictionary methods

MethodWhat it does
get(k, default)Value for k, or default if missing
keys(), values(), items()Views of the keys, values or pairs
update(other)Adds or replaces keys from another dict
pop(k)Removes k and returns its value
popitem()Removes and returns the last inserted pair
setdefault(k, d)Returns k‘s value, inserting d first if missing
copy()Shallow copy
clear()Removes everything
dict.fromkeys(keys, v)New dict with each key set to v

Sort a dictionary

Python
scores = {"Asha": 88, "Ravi": 74, "Meena": 93}print(sorted(scores))                                    # keysprint(sorted(scores.items(), key=lambda kv: kv[1], reverse=True))ranked = dict(sorted(scores.items(), key=lambda kv: kv[1], reverse=True))print(ranked)
Output
['Asha', 'Meena', 'Ravi']
[('Meena', 93), ('Asha', 88), ('Ravi', 74)]
{'Meena': 93, 'Asha': 88, 'Ravi': 74}

Check your understanding

Predict the output

d = {"a": 1, "b": 2}d["a"] += 10d.setdefault("c", 3)d.setdefault("a", 99)print(d, d.get("z", 0))

Quick quiz

1. What does d.get("x") return when “x” is not a key?

2. Which loop gives both keys and values?

3. Which of these can NOT be a dictionary key?

4. In a | b, if both dicts have key “x”, whose value is kept?

Exercise: invert a dictionary

Swap keys and values of a country-code dict, then look up the code for “India”.

Input
{"IN": "India", "US": "United States", "JP": "Japan"}
Expected output
{'India': 'IN', 'United States': 'US', 'Japan': 'JP'}
IN
Hint 1

A dict comprehension: {v: k for k, v in codes.items()}.

Program Practice

Python dictionary FAQ

Are Python dictionaries ordered?

Yes. Since Python 3.7, dictionaries preserve insertion order.

How do I check if a key exists in a dictionary?

Use in: if "email" in user:. Use get() when you also want the value.

How do I merge two dictionaries in Python?

Use a | b (Python 3.9+) or {a, b} to create a new dict, or a.update(b) to change a in place.

What is the difference between dict.get() and dict[key]?

dict[key] raises KeyError if the key is missing. dict.get(key) returns None or a default instead.