Data Structures
Level: 3 | Version: v1.0 | Author: Meptrasoft
Data Structures at a Glance
A data structure is a way to organize data so a program can store it, access it, update it, and process it easily.
Python provides several built-in data structures. In this module, we will focus on strings, lists, tuples, sets, and dictionaries.
Strings
What is a String?
A string is a sequence of characters used to store text.
student_name = "Arun Kumar"
The value "Arun Kumar" is a string.
Strings can contain:
- Letters
- Numbers
- Spaces
- Special characters
message = "Hello Python!"
student_id = "STU101"
Why Do We Use Strings?
Strings are used to store and process text data.
Real-world examples:
- Student names
- Email addresses
- User input
- Password text
- File names
- API text data
- Log messages
- Resume content
Example:
student_name = "Arun Kumar"
In a real application, we may need to:
- Remove extra spaces
- Convert text to lowercase
- Search for a word
- Replace text
- Split the name
- Validate the input
Python string methods help us perform these operations.
Key Features of Strings
| Feature | Meaning |
|---|---|
| Ordered | Characters maintain their position |
| Immutable | Characters cannot be changed directly |
| Indexed | Characters can be accessed using indexes |
| Iterable | Can be processed character by character |
| Supports Slicing | Part of a string can be extracted |
Creating a String
Single Quotes
student_name = 'Arun Kumar'
Double Quotes
student_name = "Arun Kumar"
Both are valid.
Triple Quotes
Triple quotes are used for multi-line strings.
profile = """Arun Kumar
CSE Student
Python Developer"""
Accessing String Characters
Strings support indexing.
student_name = "Arun Kumar"
print(student_name[0]) # A
print(student_name[1]) # r
print(student_name[-1]) # r
- Index
0→ first character - Index
-1→ last character
Positive and negative indexing are covered separately in the Indexing topic.
Strings are Immutable
Strings cannot be changed directly.
student_name = "Arun"
student_name[0] = "K"
Error:
Output:
TypeError: 'str' object does not support item assignment
Correct Approach
Create a new string.
student_name = "Arun"
student_name = "K" + student_name[1:]
print(student_name)
Output:
Krun
Important: String methods usually return a new string because strings are immutable.
String Length
Use len() to count characters.
student_name = "Arun Kumar"
print(len(student_name))
Output:
10
Spaces are also counted as characters.
Cleaning User Input
Consider input received from a form:
student_name = " Arun Kumar "
The string contains unwanted spaces.
strip()
Removes spaces from both ends.
student_name = " Arun Kumar "
student_name = student_name.strip()
print(student_name)
Output:
Arun Kumar
lstrip()
Removes spaces from the left side.
student_name = " Arun Kumar "
student_name = student_name.lstrip()
rstrip()
Removes spaces from the right side.
student_name = " Arun Kumar "
student_name = student_name.rstrip()
strip() vs lstrip() vs rstrip()
| Method | Removes From |
|---|---|
strip() |
Both sides |
lstrip() |
Left side |
rstrip() |
Right side |
Changing String Case
Let's use:
student_name = "Arun Kumar"
lower()
Converts text to lowercase.
student_name = "Arun Kumar"
print(student_name.lower())
Output:
arun kumar
upper()
Converts text to uppercase.
student_name = "Arun Kumar"
print(student_name.upper())
Output:
ARUN KUMAR
title()
Converts the first character of each word to uppercase.
student_name = "Arun Kumar"
print(student_name.title())
Output:
Arun Kumar
capitalize()
Converts the first character of the string to uppercase and the remaining characters to lowercase.
message = "python DEVELOPER"
print(message.capitalize())
Output:
Python developer
swapcase()
Changes uppercase to lowercase and lowercase to uppercase.
student_name = "Arun Kumar"
print(student_name.swapcase())
Output:
aRUN kUMAR
String Case Methods
| Method | Purpose |
|---|---|
lower() |
Convert to lowercase |
upper() |
Convert to uppercase |
title() |
Capitalize each word |
capitalize() |
Capitalize the string's first character and lowercase the rest |
swapcase() |
Swap uppercase and lowercase |
Searching in a String
Let's use a placement skill string.
skills = "Python SQL Java"
find()
Returns the starting index of the first matching text.
skills = "Python SQL Java"
print(skills.find("SQL"))
Output:
7
If the value is not found:
skills = "Python SQL Java"
print(skills.find("C++"))
Output:
-1
index()
Also returns the index of matching text.
skills = "Python SQL Java"
print(skills.index("SQL"))
Output:
7
If the value does not exist, index() raises a ValueError.
find() vs index()
| Method | Value Found | Value Not Found |
|---|---|---|
find() |
Returns index | Returns -1 |
index() |
Returns index | Raises ValueError |
Placement Favorite: Difference between find() and index().
Checking Whether Text Exists
Use in and not in.
skills = "Python SQL Java"
print("Python" in skills) # True
print("C++" in skills) # False
print("C++" not in skills) # True
Replacing Text
Use replace() to replace text.
skills = "Python SQL Java"
skills = skills.replace("Java", "C++")
print(skills)
Output:
Python SQL C++
The original string is not modified directly.
replace() returns a new string.
Counting Text
Use count() to count occurrences.
skills = "Python SQL Python Java"
print(skills.count("Python"))
Output:
2
Splitting a String
Real applications often receive data as text.
skills = "Python,SQL,Java"
Use split() to convert the string into a list.
skills = "Python,SQL,Java"
skill_list = skills.split(",")
print(skill_list)
Output:
['Python', 'SQL', 'Java']
Joining Strings
Use join() to combine multiple strings.
skill_list = ["Python", "SQL", "Java"]
skills = ", ".join(skill_list)
print(skills)
Output:
Python, SQL, Java
split() vs join()
| Method | Conversion |
|---|---|
split() |
String → List |
join() |
Iterable of strings → String |
"Python,SQL,Java"
↓ split()
["Python", "SQL", "Java"]
↓ join()
"Python, SQL, Java"
Very Important in Real Projects: API data processing, CSV-like text, form data, and file processing.
Checking String Content
Python provides methods to validate text.
| Method | Checks |
|---|---|
isalpha() |
Only alphabetic characters |
isdigit() |
Only digit characters |
isalnum() |
Only letters and digits |
isspace() |
Only whitespace characters |
islower() |
Lowercase |
isupper() |
Uppercase |
isalpha()
name = "Arun"
print(name.isalpha()) # True
name = "Arun123"
print(name.isalpha()) # False
isdigit()
student_id = "101"
print(student_id.isdigit()) # True
isalnum()
student_id = "STU101"
print(student_id.isalnum()) # True
Real-Time Input Validation
Consider a student registration form.
student_name = "Arun"
age = "21"
student_id = "STU101"
print(student_name.isalpha()) # True
print(age.isdigit()) # True
print(student_id.isalnum()) # True
These methods are useful for basic input validation.
Checking Start and End
startswith()
Checks whether a string starts with specific text.
student_id = "STU101"
print(student_id.startswith("STU"))
Output:
True
endswith()
Checks whether a string ends with specific text.
resume_file = "arun_resume.pdf"
print(resume_file.endswith(".pdf"))
Output:
True
Real-Time Use
resume_file = "arun_resume.pdf"
if resume_file.endswith(".pdf"):
print("Valid resume format")
Useful for:
- File extension checking
- URL checking
- ID prefix validation
- Email/domain checks
String Concatenation
Strings can be combined using +.
first_name = "Arun"
last_name = "Kumar"
full_name = first_name + " " + last_name
print(full_name)
Output:
Arun Kumar
String Repetition
Use * to repeat a string.
symbol = "-"
print(symbol * 20)
Output:
--------------------
String Formatting with f-Strings
Consider student placement data:
student_name = "Arun Kumar"
cgpa = 8.5
skill = "Python"
Using an f-string:
skill = 'Sample'
cgpa = 8.5
student_name = "Arun Kumar"
message = f"{student_name} has a CGPA of {cgpa} and knows {skill}."
print(message)
Output:
Arun Kumar has a CGPA of 8.5 and knows Sample.
F-strings make formatted output clean and readable.
Escape Characters
Escape characters represent special characters inside strings.
| Escape Character | Meaning |
|---|---|
\n |
New line |
\t |
Tab |
\\ |
Backslash |
\" |
Double quote |
\' |
Single quote |
New Line
print("Name: Arun\nSkill: Python")
Output:
Name: Arun
Skill: Python
Tab
print("Name\tCGPA")
print("Arun\t8.5")
Common String Methods
| Method | Purpose |
|---|---|
strip() |
Remove characters from both ends; whitespace by default |
lower() |
Convert to lowercase |
upper() |
Convert to uppercase |
title() |
Convert each word to title case |
capitalize() |
Capitalize first character and lowercase the rest |
find() |
Find text and return -1 if missing |
index() |
Find text and raise error if missing |
replace() |
Replace text |
count() |
Count occurrences |
split() |
Split string into a list |
join() |
Join an iterable of strings |
startswith() |
Check starting text |
endswith() |
Check ending text |
isalpha() |
Check alphabetic characters |
isdigit() |
Check digit characters |
isalnum() |
Check letters and digits |
Common Fresher Mistakes
| ✗ Mistake | Problem | ✓ Correct Understanding |
|---|---|---|
name[0] = "K" |
Strings are immutable | Create a new string |
age = input() expecting integer |
input() returns a string |
Use int(input()) |
find() expected to raise an error |
find() returns -1 |
index() raises ValueError |
skills.split() expecting original string to change |
Strings are immutable | Store the returned value |
"".join([1, 2, 3]) |
Items are not strings | Convert items to strings |
name.isalpha() on "Arun Kumar" expecting True |
Space is not alphabetic | Validate words separately if needed |
Forgetting spaces in + |
Strings join exactly as given | Add " " manually |
Practical Example — Cleaning Placement Form Data
student_name = " arun kumar "
skills = "Python,SQL,Java"
resume_file = "arun_resume.pdf"
student_name = student_name.strip().title()
skill_list = skills.split(",")
print("Student:", student_name)
print("Skills:", skill_list)
if resume_file.endswith(".pdf"):
print("Valid Resume")
Output:
Student: Arun Kumar
Skills: ['Python', 'SQL', 'Java']
Valid Resume
This is similar to text cleaning and validation performed in real applications.
Placement Quick Points
- A string is a sequence of characters.
- Strings are ordered and immutable.
- Strings support indexing and slicing.
- String indexing starts from
0. - String methods return new strings.
strip()removes characters from both ends; with no argument, it removes surrounding whitespace.find()returns-1when text is not found.index()raisesValueErrorwhen text is not found.split()converts a string into a list.join()combines an iterable of strings into a string.replace()returns a new string.inchecks whether text exists.- f-strings are used for clean string formatting.
startswith()andendswith()are useful for validation.
Interview Questions
- What is a string in Python?
- A string is an immutable sequence of characters.
- Are strings mutable or immutable?
- Immutable.
- Can strings be indexed?
- Yes.
- What is the difference between
find()andindex()? find()returns-1when the value is missing.index()raises aValueError.- What does
strip()do? - It removes leading and trailing whitespace by default. If characters are provided, it removes those characters from both ends.
- What is the difference between
split()andjoin()? split()converts a string into a list.join()combines an iterable of strings into a string.- Do string methods modify the original string?
- No. Strings are immutable.
- How do you check whether a string contains only digits?
value.isdigit().- What is an f-string?
- A readable way to insert expressions into a formatted string.
- What does
find()return if the value is not found? -1.- Can we change a character using an index?
- No. Strings do not support item assignment.
- What does
join()require? - An iterable containing strings.
Practice
Use:
student_name = " arun kumar "
skills = "Python,SQL,Java"
student_id = "STU101"
resume_file = "arun_resume.pdf"
- Remove extra spaces from
student_name. - Convert the student name to title case.
- Convert the name to uppercase.
- Find the index of
"SQL"inskills. - Replace
"Java"with"C++". - Convert
skillsinto a list. - Join the skill list using
" | ". - Check whether
student_idstarts with"STU". - Check whether
resume_fileends with".pdf". - Check whether
"Python"exists inskills. - Count how many times
"Python"appears. - Explain the difference between
find()andindex(). - Find the error:
student_name = " arun kumar "
student_name[0] = "A"
- Predict the output:
text = "Python"
print(text.find("Java"))
- Explain why this causes an error:
",".join([10, 20, 30])
Lists
What is a List?
A list is a collection used to store multiple values under one name.
skills = ["Python", "SQL", "Java"]
Instead of creating multiple variables:
skill1 = "Python"
skill2 = "SQL"
skill3 = "Java"
We can store all values in one list.
skills = ["Python", "SQL", "Java"]
Why Do We Use Lists?
Lists help us store, access, update, and manage multiple values together.
marks = [85, 90, 78, 92]
Real-world examples:
- Student marks
- Product names
- Employee records
- File names
- API results
- Model predictions
Key Features of Lists
| Feature | Meaning |
|---|---|
| Ordered | Maintains element order |
| Mutable | Elements can be changed |
| Dynamic | Can grow or shrink |
| Allows Duplicates | Same value can appear multiple times |
| Heterogeneous | Can store different data types |
| Indexed | Elements can be accessed using indexes |
Creating a List
Empty List
numbers = []
List with Values
numbers = [10, 20, 30]
Mixed Data Types
data = [10, "Python", 3.14, True]
Duplicate Values
numbers = [10, 20, 20, 30]
Lists allow duplicate values.
Nested List
A list can contain another list.
data = [10, [20, 30], 40]
Accessing List Elements
List elements are accessed using an index.
skills = ["Python", "SQL", "Java"]
print(skills[0]) # Python
print(skills[1]) # SQL
print(skills[-1]) # Java
- Index
0→ first element - Index
-1→ last element
Positive and negative indexing are covered separately in the Indexing topic.
Updating List Elements
Lists are mutable, so their elements can be changed.
skills = ["Python", "SQL", "Java"]
skills[2] = "C++"
print(skills)
Output:
['Python', 'SQL', 'C++']
Adding Elements
append()
Adds one item to the end of the list.
skills = ["Python", "SQL"]
skills.append("Java")
print(skills)
Output:
['Python', 'SQL', 'Java']
extend()
Adds multiple elements from an iterable.
skills = ["Python", "SQL"]
skills.extend(["Java", "C++"])
print(skills)
Output:
['Python', 'SQL', 'Java', 'C++']
insert()
Adds an element at a specific index.
skills = ["Python", "Java"]
skills.insert(1, "SQL")
print(skills)
Output:
['Python', 'SQL', 'Java']
append() vs extend()
| Method | Adds | Example | Result |
|---|---|---|---|
append() |
One item | a.append([3, 4]) |
[1, 2, [3, 4]] |
extend() |
Elements from an iterable | a.extend([3, 4]) |
[1, 2, 3, 4] |
Example:
a = [1, 2]
a.append([3, 4])
print(a)
Output:
[1, 2, [3, 4]]
a = [1, 2]
a.extend([3, 4])
print(a)
Output:
[1, 2, 3, 4]
Placement Favorite: append() vs extend().
Removing Elements
remove()
Removes the first matching value.
numbers = [10, 20, 30, 20]
numbers.remove(20)
print(numbers)
Output:
[10, 30, 20]
pop()
Removes and returns an element.
numbers = [10, 20, 30]
removed = numbers.pop()
print(removed) # 30
print(numbers) # [10, 20]
Remove using an index:
numbers = [10, 20, 30]
numbers.pop(1)
clear()
Removes all elements.
numbers = [10, 20, 30]
numbers.clear()
print(numbers) # []
remove() vs pop()
| Method | Removes By | Returns Removed Value |
|---|---|---|
remove() |
Value | No |
pop() |
Index | Yes |
numbers = [10, 20, 30]
numbers.remove(20) # Remove value
numbers.pop(0) # Remove by index
Searching and Counting
index()
Returns the index of the first matching value.
numbers = [10, 20, 30]
print(numbers.index(20)) # 1
count()
Counts how many times a value appears.
numbers = [10, 20, 20, 30]
print(numbers.count(20)) # 2
Membership Operators
Use in and not in to check whether a value exists.
skills = ["Python", "SQL"]
print("Python" in skills) # True
print("Java" not in skills) # True
Sorting a List
sort()
Sorts the original list.
numbers = [40, 10, 30, 20]
numbers.sort()
print(numbers)
Output:
[10, 20, 30, 40]
Descending order:
numbers = [40, 10, 30, 20]
numbers.sort(reverse=True)
sort() vs sorted()
sort() |
sorted() |
|---|---|
| List method | Built-in function |
| Changes the original list | Returns a new sorted list |
Returns None |
Returns a sorted list |
numbers = [30, 10, 20]
result = numbers.sort()
print(result) # None
Using sorted():
numbers = [30, 10, 20]
result = sorted(numbers)
print(result) # [10, 20, 30]
print(numbers) # [30, 10, 20]
Common Placement Question: Why does list.sort() return None?
Because it modifies the original list in place.
Reversing a List
The reverse() method reverses the original list.
numbers = [10, 20, 30]
numbers.reverse()
print(numbers)
Output:
[30, 20, 10]
Useful Built-in Functions
| Function | Purpose |
|---|---|
len() |
Number of elements |
max() |
Largest value |
min() |
Smallest value |
sum() |
Sum of numeric values |
sorted() |
Returns a sorted list |
marks = [80, 90, 70, 85]
print(len(marks)) # 4
print(max(marks)) # 90
print(min(marks)) # 70
print(sum(marks)) # 325
Copying a List
Consider this code:
a = [10, 20, 30]
b = a
b.append(40)
print(a)
Output:
[10, 20, 30, 40]
Why did a change?
Because a and b refer to the same list object.
Use copy() to create a separate shallow copy.
a = [10, 20, 30]
b = a.copy()
b.append(40)
print(a) # [10, 20, 30]
print(b) # [10, 20, 30, 40]
Shallow copy and deep copy are covered separately in the Copying Objects topic.
Common List Methods
| Method | Purpose |
|---|---|
append() |
Add one item |
extend() |
Add elements from an iterable |
insert() |
Add at a specific index |
remove() |
Remove first matching value |
pop() |
Remove and return an item |
index() |
Find the index of a value |
count() |
Count occurrences |
sort() |
Sort the original list |
reverse() |
Reverse the original list |
copy() |
Create a shallow copy |
clear() |
Remove all items |
Common Fresher Mistakes
| ✗ Mistake | Problem | ✓ Correct Understanding |
|---|---|---|
numbers[1] expecting first item |
Index starts at 0 |
Use numbers[0] |
data.extend(40) |
int is not iterable |
Use data.append(40) |
result = numbers.sort() |
sort() returns None |
Use sorted(numbers) if a new list is needed |
b = a expecting a copy |
Both names refer to the same list | Use a.copy() |
numbers.remove(1) expecting index removal |
remove() removes by value |
Use pop(1) for index |
| Modifying a list expecting immutability | Lists are mutable | List elements can change |
Practical Example — Student Marks
marks = [75, 85, 60, 90]
marks.append(80)
print("Marks:", marks)
print("Highest:", max(marks))
print("Lowest:", min(marks))
print("Total:", sum(marks))
print("Average:", sum(marks) / len(marks))
Output:
Marks: [75, 85, 60, 90, 80]
Highest: 90
Lowest: 60
Total: 390
Average: 78.0
Placement Quick Points
- A list stores multiple values.
- Lists are ordered and mutable.
- Lists allow duplicate values.
- Lists can store different data types.
- List indexing starts from
0. append()adds one item.extend()adds elements from an iterable.remove()removes by value.pop()removes by index and returns the removed item.sort()modifies the original list.sorted()returns a new sorted list.b = adoes not create a copy.- Use
copy()to create a shallow copy.
Interview Questions
- What is a list in Python?
- A list is an ordered and mutable collection of elements.
- Can a list contain duplicate values?
- Yes.
- Can a list store different data types?
- Yes.
- What is the difference between
append()andextend()? append()adds one item, whileextend()adds elements from an iterable.- What is the difference between
remove()andpop()? remove()removes by value.pop()removes by index and returns the removed item.- What is the difference between
sort()andsorted()? sort()changes the original list.sorted()returns a new sorted list.- Is a list mutable or immutable?
- Mutable.
- Does
b = acopy a list? - No. Both names refer to the same list.
- How do you create a shallow copy of a list?
b = a.copy().- What does
list.sort()return? None.
Practice
- Create a list of five student marks.
- Add a new mark using
append(). - Add three marks using
extend(). - Insert a mark at index
2. - Remove a value using
remove(). - Remove the last element using
pop(). - Find how many times
10appears in a list. - Sort a list in ascending and descending order.
- Find the maximum, minimum, and sum of a numeric list.
- Explain the output:
a = [1, 2, 3]
b = a
b.append(4)
print(a)
- Find the error:
data = [10, 20]
data.extend(30)
- Explain why this prints
None:
numbers = [3, 1, 2]
result = numbers.sort()
print(result)
Tuples
What is a Tuple?
A tuple is a collection used to store multiple values under one name.
skills = ("Python", "SQL", "Java")
A tuple is similar to a list, but it is immutable.
Immutable means tuple elements cannot be replaced, added, or removed after creation.
Why Do We Use Tuples?
Tuples are useful when the collection structure should remain fixed and unchanged.
coordinates = (10, 20)
Real-world examples:
- Coordinates
- RGB color values
- Date values
- Database records
- Fixed configuration values
- Function return values
Key Features of Tuples
| Feature | Meaning |
|---|---|
| Ordered | Maintains element order |
| Immutable | Cannot replace, add, or remove elements |
| Allows Duplicates | Same value can appear multiple times |
| Heterogeneous | Can store different data types |
| Indexed | Elements can be accessed using indexes |
Creating a Tuple
Empty Tuple
data = ()
Tuple with Values
numbers = (10, 20, 30)
Mixed Data Types
data = (10, "Python", 3.14, True)
Duplicate Values
numbers = (10, 20, 20, 30)
Tuples allow duplicate values.
Nested Tuple
A tuple can contain another tuple.
data = (10, (20, 30), 40)
Creating a Single-Element Tuple
A single-element tuple must contain a comma.
data = (10,)
Without the comma:
data = (10)
print(type(data))
Output:
<class 'int'>
With the comma:
data = (10,)
print(type(data))
Output:
<class 'tuple'>
Placement Favorite: The comma creates a single-element tuple, not the parentheses alone.
Accessing Tuple Elements
Tuple elements are accessed using an index.
skills = ("Python", "SQL", "Java")
print(skills[0]) # Python
print(skills[1]) # SQL
print(skills[-1]) # Java
- Index
0→ first element - Index
-1→ last element
Positive and negative indexing are covered separately in the Indexing topic.
Tuple is Immutable
Tuple elements cannot be replaced after creation.
skills = ("Python", "SQL", "Java")
skills[1] = "C++"
Error:
Output:
TypeError: 'tuple' object does not support item assignment
This is the main difference between a list and tuple.
Can We Add or Remove Tuple Elements?
No.
Tuples do not support methods such as:
append()
extend()
insert()
remove()
pop()
clear()
These methods change the collection, but tuples are immutable.
Tuple Methods
Tuples have only two commonly used methods.
| Method | Purpose |
|---|---|
count() |
Counts occurrences of a value |
index() |
Finds the index of a value |
count()
Counts how many times a value appears.
numbers = (10, 20, 20, 30)
print(numbers.count(20)) # 2
index()
Returns the index of the first matching value.
numbers = (10, 20, 30)
print(numbers.index(20)) # 1
Membership Operators
Use in and not in to check whether a value exists.
skills = ("Python", "SQL", "Java")
print("Python" in skills) # True
print("C++" not in skills) # True
Useful Built-in Functions
| Function | Purpose |
|---|---|
len() |
Number of elements |
max() |
Largest value |
min() |
Smallest value |
sum() |
Sum of numeric values |
sorted() |
Returns a sorted list |
marks = (80, 90, 70, 85)
print(len(marks)) # 4
print(max(marks)) # 90
print(min(marks)) # 70
print(sum(marks)) # 325
Important: sorted() Returns a List
numbers = (30, 10, 20)
result = sorted(numbers)
print(result)
print(type(result))
Output:
[10, 20, 30]
<class 'list'>
sorted() does not return a tuple.
Tuple Packing
Storing multiple values in a tuple is called tuple packing.
student = ("Arun", 21, 8.5)
Python also allows packing without parentheses.
student = "Arun", 21, 8.5
print(type(student))
Output:
<class 'tuple'>
Tuple Unpacking
Assigning tuple elements to multiple names is called tuple unpacking.
student = ("Arun", 21, 8.5)
name, age, cgpa = student
print(name)
print(age)
print(cgpa)
Output:
Arun
21
8.5
The number of names and values should match.
student = ("Arun", 21, 8.5)
name, age = student
This causes a ValueError.
Swapping Using Tuple Unpacking
Python uses packing and unpacking while swapping values.
a = 10
b = 20
a, b = b, a
print(a, b)
Output:
20 10
Tuple with Mutable Elements
A tuple itself is immutable, but it can contain a mutable object such as a list.
data = (10, [20, 30], 40)
data[1].append(50)
print(data)
Output:
(10, [20, 30, 50], 40)
Why Did the Tuple Change?
The tuple still refers to the same list object.
We did not replace the tuple element. We modified the list stored inside it.
data = (10, [20, 30], 40)
data[1] = [100, 200] # Error
Replacing a tuple element is not allowed.
Interview Important: Tuple immutability does not automatically make every object inside the tuple immutable.
List vs Tuple
| Feature | List | Tuple |
|---|---|---|
| Syntax | [ ] |
( ) |
| Ordered | Yes | Yes |
| Mutable | Yes | No |
| Duplicates | Yes | Yes |
| Indexed | Yes | Yes |
| Mixed Data Types | Yes | Yes |
| Methods | Many | count(), index() |
| Best Used For | Changeable data | Fixed data |
Converting List and Tuple
List to Tuple
numbers = [10, 20, 30]
result = tuple(numbers)
print(result)
Output:
(10, 20, 30)
Tuple to List
numbers = (10, 20, 30)
result = list(numbers)
print(result)
Output:
[10, 20, 30]
How to Modify a Tuple?
A tuple cannot be modified directly.
If modification is required:
- Convert tuple to list
- Modify the list
- Convert it back to tuple
numbers = (10, 20, 30)
data = list(numbers)
data.append(40)
numbers = tuple(data)
print(numbers)
Output:
(10, 20, 30, 40)
Common Fresher Mistakes
| ✗ Mistake | Problem | ✓ Correct Understanding |
|---|---|---|
(10) considered a tuple |
It creates an int |
Use (10,) |
Trying tuple.append() |
Tuples are immutable | Use a list for changeable data |
Trying data[0] = 100 |
Item assignment is not supported | Tuple elements cannot be replaced |
Expecting sorted(tuple) to return tuple |
sorted() returns a list |
Convert using tuple(sorted(data)) |
| Mismatched unpacking | Number of names and values differ | Names should match values |
| Thinking all objects inside a tuple are immutable | Tuple may contain mutable objects | Inner mutable objects can change |
Practical Example — Student Record
student = ("Arun", 21, 8.5)
name, age, cgpa = student
print("Name:", name)
print("Age:", age)
print("CGPA:", cgpa)
Output:
Name: Arun
Age: 21
CGPA: 8.5
A tuple is suitable here when the record values are treated as fixed data.
Placement Quick Points
- A tuple stores multiple values.
- Tuples are ordered and immutable.
- Tuples allow duplicate values.
- Tuples can store different data types.
- Tuple indexing starts from
0. - A single-element tuple requires a comma.
- Tuples have
count()andindex()methods. - Tuple packing stores multiple values together.
- Tuple unpacking assigns values to multiple names.
sorted(tuple)returns a list.- A tuple can contain mutable objects.
- Tuple immutability prevents replacing its elements.
Interview Questions
- What is a tuple in Python?
- A tuple is an ordered and immutable collection of elements.
- What is the main difference between a list and a tuple?
- A list is mutable, while a tuple is immutable.
- How do you create a single-element tuple?
data = (10,).- Why is
(10)not a tuple? - Parentheses alone do not create a single-element tuple. The comma is required.
- What methods are available for tuples?
count()andindex().- Can a tuple contain duplicate values?
- Yes.
- Can a tuple contain different data types?
- Yes.
- What is tuple packing?
- Storing multiple values together as a tuple.
- What is tuple unpacking?
- Assigning tuple values to multiple names.
- Can a tuple contain a list?
- Yes.
- Can the list inside a tuple be modified?
- Yes, because the list itself is mutable.
- What does
sorted()return when used with a tuple? - A list.
Practice
- Create a tuple containing five numbers.
- Create a single-element tuple.
- Access the first and last elements of a tuple.
- Count how many times
10appears. - Find the index of
20. - Check whether
"Python"exists in a tuple. - Find the maximum, minimum, and sum of a numeric tuple.
- Pack a student's name, age, and CGPA into a tuple.
- Unpack the student tuple into three variables.
- Convert a list into a tuple.
- Convert a tuple into a list.
- Predict the output:
data = (10)
print(type(data))
- Find the error:
numbers = (10, 20, 30)
numbers.append(40)
- Explain the output:
data = (10, [20, 30])
data[1].append(40)
print(data)
Indexing
Indexing means accessing an element using its position number, called an index.
numbers = [10, 20, 30, 40, 50]
Python supports two types of indexing:
- Positive Indexing — starts from
0 - Negative Indexing — starts from
-1
Positive and Negative Indexing
| Element | 10 |
20 |
30 |
40 |
50 |
|---|---|---|---|---|---|
| Positive Index | 0 |
1 |
2 |
3 |
4 |
| Negative Index | -5 |
-4 |
-3 |
-2 |
-1 |
Positive Indexing
Positive indexing starts from 0 and moves from left to right.
numbers = [10, 20, 30, 40, 50]
print(numbers[0]) # 10
print(numbers[2]) # 30
print(numbers[4]) # 50
Important
The first element is at index 0, not 1.
numbers = [10, 20, 30, 40, 50]
numbers[0] # First element
numbers[1] # Second element
Negative Indexing
Negative indexing starts from -1 and accesses elements from right to left.
numbers = [10, 20, 30, 40, 50]
print(numbers[-1]) # 50
print(numbers[-2]) # 40
print(numbers[-5]) # 10
-1 always refers to the last element.
Positive vs Negative Indexing
| Index Type | Starts From | Direction | Example |
|---|---|---|---|
| Positive | 0 |
Left → Right | numbers[0] → 10 |
| Negative | -1 |
Right → Left | numbers[-1] → 50 |
The same element can be accessed using either a positive or negative index.
numbers = [10, 20, 30, 40, 50]
print(numbers[0]) # 10
print(numbers[-5]) # 10
print(numbers[4]) # 50
print(numbers[-1]) # 50
Index Range
For a list containing 5 elements:
numbers = [10, 20, 30, 40, 50]
| Index Type | Valid Range |
|---|---|
| Positive Index | 0 to 4 |
| Negative Index | -1 to -5 |
General Rule
For a collection with n elements:
- Positive index:
0ton - 1 - Negative index:
-1to-n
IndexError
Accessing an index outside the valid range causes an IndexError.
numbers = [10, 20, 30, 40, 50]
print(numbers[5]) # IndexError
print(numbers[-6]) # IndexError
Valid indexes are:
Output:
Positive: 0, 1, 2, 3, 4
Negative: -1, -2, -3, -4, -5
Indexing Different Data Types
Indexing is not limited to lists. It can also be used with other ordered sequence types.
String
name = "Python"
print(name[0]) # P
print(name[-1]) # n
List
skills = ["Python", "SQL", "Java"]
print(skills[0]) # Python
print(skills[-1]) # Java
Tuple
numbers = (10, 20, 30)
print(numbers[1]) # 20
print(numbers[-1]) # 30
Common Fresher Mistakes
| ✗ Mistake | Problem | ✓ Correct |
|---|---|---|
numbers[1] expecting first element |
Index starts from 0 |
numbers[0] |
numbers[len(numbers)] |
Index is out of range | numbers[len(numbers) - 1] |
numbers[-6] for a 5-item list |
Negative index is out of range | Minimum is -5 |
Thinking -1 is the first element |
-1 means last element |
Use 0 for first |
Useful Access Patterns
numbers = [10, 20, 30, 40, 50]
print(numbers[0]) # First element
print(numbers[-1]) # Last element
print(numbers[1]) # Second element
print(numbers[-2]) # Second last element
Placement Quick Points
- Indexing is used to access an element by its position.
- Positive indexing starts from
0. - Negative indexing starts from
-1. 0represents the first element.-1represents the last element.- For
nelements, the last positive index isn - 1. - For
nelements, the first negative index is-n. - An invalid index raises
IndexError. - Strings, lists, and tuples support indexing.
Interview Questions
- What is indexing in Python?
- Indexing is accessing an element using its position number.
- What is the index of the first element?
0.- What is the index of the last element?
-1orlen(collection) - 1.- What happens when an invalid index is accessed?
- Python raises an
IndexError. - What is the valid positive index range for 5 elements?
0to4.- What is the valid negative index range for 5 elements?
-1to-5.- Do dictionaries support positional indexing?
- No. Dictionaries are accessed using keys, not positional indexes.
Practice
Use:
numbers = [10, 20, 30, 40, 50]
- Access the first element.
- Access the last element using negative indexing.
- Access
30using both positive and negative indexing. - Access the second-last element.
- What happens with
numbers[5]? - What happens with
numbers[-6]? - Find the output:
numbers = [10, 20, 30, 40, 50]
print(numbers[-len(numbers)])
Slicing
Slicing means accessing a portion of a sequence, instead of a single element.
numbers = [10, 20, 30, 40, 50]
numbers = [10, 20, 30, 40, 50]
numbers = [10, 20, 30, 40, 50]
numbers = [10, 20, 30, 40, 50]
print(numbers[1:4]) # [20, 30, 40]
Slicing works on any ordered sequence, such as strings and lists.
Basic Syntax
sequence[start:stop]
start— the index where the slice begins (included)stop— the index where the slice ends (excluded)
The element at stop is not part of the result.
numbers = [10, 20, 30, 40, 50]
print(numbers[1:4]) # [20, 30, 40]
Here the slice starts at index 1 (20) and stops before index 4 (50).
Omitting start or stop
If start is omitted, the slice begins at the start of the sequence.
If stop is omitted, the slice runs to the end of the sequence.
numbers = [10, 20, 30, 40, 50]
print(numbers[:3]) # [10, 20, 30]
print(numbers[2:]) # [30, 40, 50]
print(numbers[:]) # [10, 20, 30, 40, 50]
numbers[:] returns all the elements.
Slicing Strings
Strings support slicing in the same way.
name = "Python"
print(name[0:3]) # Pyt
print(name[3:]) # hon
print(name[:2]) # Py
A common use is skipping the first character:
student_name = "Aarav"
print(student_name[1:]) # arav
Negative Indices in Slicing
Slicing also works with negative indices, counting from the right.
numbers = [10, 20, 30, 40, 50]
print(numbers[-3:]) # [30, 40, 50]
print(numbers[:-2]) # [10, 20, 30]
name = "Python"
print(name[-3:]) # hon
The step Value
Slicing can take a third value, called the step.
sequence[start:stop:step]
The step decides how many positions to move for each element.
numbers = [10, 20, 30, 40, 50]
print(numbers[0:5:2]) # [10, 30, 50]
Here the slice takes every second element.
Reversing with Slicing
A step of -1 reverses the sequence.
sequence[::-1]
numbers = [10, 20, 30, 40, 50]
print(numbers[::-1]) # [50, 40, 30, 20, 10]
name = "Python"
print(name[::-1]) # nohtyP
Slicing vs Indexing
| Feature | Indexing | Slicing |
|---|---|---|
| Access | A single element | A range of elements |
| Syntax | sequence[i] |
sequence[start:stop:step] |
| Returns | One item | A new sequence (same type) |
| Example | numbers[1] → 20 |
numbers[1:3] → [20, 30] |
Common Fresher Mistakes
| ✗ Mistake | Problem | ✓ Correct |
|---|---|---|
numbers[1:4] expecting 50 too |
stop is excluded |
Use numbers[1:5] |
numbers[4:1] expecting a result |
start is after stop, so empty |
Use numbers[1:4] |
| Thinking slicing changes the original | Slicing returns a new sequence | Original stays unchanged |
Placement Quick Points
- Slicing accesses a range of elements.
- Syntax is
sequence[start:stop:step]. startis included,stopis excluded.- Omitting
startbegins from the first element. - Omitting
stopruns to the last element. - Negative indices count from the right.
sequence[::-1]reverses the sequence.- Slicing returns a new sequence and leaves the original unchanged.
- Strings and lists both support slicing.
Interview Questions
- What is slicing in Python?
- Slicing is accessing a portion (range) of a sequence using
start:stop:step. - Is the
stopindex included in a slice? - No. The
stopindex is excluded. - What does
sequence[::-1]do? - It reverses the sequence.
- What happens if you omit both
startandstop? - The whole sequence is returned.
- Does slicing modify the original sequence?
- No. It returns a new sequence and leaves the original unchanged.
Practice
Use:
numbers = [10, 20, 30, 40, 50]
name = "Python"
- Get the first three elements of
numbers. - Get the last two elements of
numbers. - Get every second element of
numbers. - Reverse
numbersusing slicing. - Get
"hon"fromname. - Reverse
nameusing slicing. - Find the output:
print(numbers[1:4])
Sets
What is a Set?
A set is a collection used to store unique values.
student_skills = {"Python", "SQL", "Java"}
Each value appears only once.
student_skills = {"Python", "SQL", "Python", "Java"}
print(student_skills)
Possible output contains only unique values:
{'Java', 'Python', 'SQL'}
The displayed order may vary because sets are unordered.
Why Do We Use Sets?
Consider skills collected from a student form:
skills = ["Python", "SQL", "Python", "Java", "SQL"]
The list contains duplicate values.
Using a set:
skills = ["Python", "SQL", "Python", "Java", "SQL"]
student_skills = set(skills)
print(student_skills)
The duplicate skills are removed.
Output:
{'Java', 'Python', 'SQL'}
Sets are useful when we need unique data and set comparisons.
Real-Time Usage
Sets are commonly used for:
- Removing duplicate values
- Comparing user skills
- Finding common skills
- Finding missing skills
- Combining unique data
- Unique user IDs
- Tags and categories
- Permission comparison
Example:
student_skills = {"Python", "SQL", "Java"}
print(required_skills = {"Python", "SQL", "Git"})
print(required_skills)
print(required_skills)
We can easily find:
- Common skills
- Missing skills
- Combined skills
Key Features of Sets
| Feature | Meaning |
|---|---|
| Unique Values | Duplicate values are removed |
| Unordered | No positional order |
| Mutable | Elements can be added or removed |
| No Indexing | Cannot access values using an index |
| Set Operations | Supports union, intersection, and difference |
Creating a Set
We will use student skills throughout this topic.
student_skills = {"Python", "SQL", "Java"}
Set with Duplicate Values
student_skills = {"Python", "SQL", "Python", "Java"}
Duplicate values are automatically removed.
Creating an Empty Set
Use set().
student_skills = set()
Do not use {}.
student_skills = {}
print(type(student_skills))
Output:
<class 'dict'>
{} creates an empty dictionary.
student_skills = set()
print(type(student_skills))
Output:
<class 'set'>
Placement Favorite: How do you create an empty set?
Accessing Set Elements
Sets do not support indexing.
student_skills = {"Python", "SQL", "Java"}
student_skills = {"Python", "SQL", "Java"}
student_skills = {"Python", "SQL", "Java"}
student_skills = ["Python", "SQL", "Git"]
print(student_skills[0])
Error:
Output:
Python
Because sets are unordered, there is no first or last element by position.
To process set values, use a loop.
student_skills = {"Python", "SQL", "Java"}
for skill in student_skills:
print(skill)
The iteration order is not guaranteed.
Checking Whether a Value Exists
Use in and not in.
student_skills = {"Python", "SQL", "Java"}
print("Python" in student_skills) # True
print("Git" in student_skills) # False
student_skills = {"Python", "SQL", "Java"}
print("Git" not in student_skills) # True
Membership checking is one of the most common uses of sets.
Adding Elements
add()
Adds one element to the set.
student_skills = {"Python", "SQL", "Java"}
student_skills.add("Git")
print(student_skills)
Now "Git" is added to the set.
Adding a Duplicate Value
student_skills = {"Python", "SQL", "Java"}
student_skills.add("Python")
No duplicate is created.
The set still contains "Python" only once.
Adding Multiple Elements
update()
Adds multiple elements from an iterable.
student_skills = {"Python", "SQL"}
student_skills.update(["Java", "Git"])
print(student_skills)
update() can accept values from lists, tuples, sets, and other iterables.
add() vs update()
| Method | Adds | Example |
|---|---|---|
add() |
One element | skills.add("Git") |
update() |
Elements from an iterable | skills.update(["Git", "Java"]) |
Placement Favorite: add() vs update().
Removing Elements
Let's use:
student_skills = {"Python", "SQL", "Java"}
remove()
Removes a specific value.
student_skills = {"Python", "SQL", "Java"}
student_skills.remove("Java")
If the value does not exist:
student_skills = {"Python", "SQL", "Java"}
student_skills.remove("Git")
Python raises a KeyError.
discard()
Removes a value if it exists.
student_skills = {"Python", "SQL", "Java"}
student_skills.discard("Java")
If the value does not exist:
student_skills = {"Python", "SQL", "Java"}
student_skills.discard("Git")
No error occurs.
remove() vs discard()
| Method | Value Exists | Value Missing |
|---|---|---|
remove() |
Removes value | Raises KeyError |
discard() |
Removes value | No error |
Placement Favorite: Difference between remove() and discard().
pop()
Removes and returns an arbitrary element.
student_skills = {"Python", "SQL", "Java"}
removed_skill = student_skills.pop()
print(removed_skill)
Because a set is unordered, do not assume which element pop() will remove.
clear()
Removes all elements.
student_skills = {"Python", "SQL", "Java"}
student_skills.clear()
print(student_skills)
Output:
set()
Comparing Student Skills
Now let's use a real placement example.
student_skills = {"Python", "SQL", "Java"}
print(required_skills = {"Python", "SQL", "Git"})
The student has:
Output:
Python, SQL, Java
The company requires:
Python, SQL, Git
We can compare these sets using set operations.
Union
Union combines all unique values from both sets.
Use | or union().
required_skills = {"Python", "SQL", "Git"}
student_skills = {"Python", "SQL", "Java"}
all_skills = student_skills | required_skills
print(all_skills)
Or:
required_skills = {"Python", "SQL", "Git"}
student_skills = {"Python", "SQL", "Java"}
all_skills = student_skills.union(required_skills)
print(all_skills)
Result contains:
Output:
{'Java', 'Git', 'Python', 'SQL'}
Meaning
Student skills OR required skills — all unique skills.
Intersection
Intersection finds values common to both sets.
Use & or intersection().
required_skills = {"Python", "SQL", "Git"}
student_skills = {"Python", "SQL", "Java"}
common_skills = student_skills & required_skills
print(common_skills)
Or:
required_skills = {"Python", "SQL", "Git"}
student_skills = {"Python", "SQL", "Java"}
common_skills = student_skills.intersection(required_skills)
print(common_skills)
Result:
Output:
{'Python', 'SQL'}
Meaning
The student already has these required skills.
Difference
Difference finds values available in one set but not the other.
Use - or difference().
Find Missing Skills
student_skills = {"Python", "SQL", "Java"}
required_skills = {"Python", "SQL", "Git"}
missing_skills = required_skills - student_skills
print(missing_skills)
Result:
Output:
{'Git'}
This is a very practical use of sets.
Required Skills - Student Skills = Missing Skills
Find Extra Skills
required_skills = {"Python", "SQL", "Git"}
student_skills = {"Python", "SQL", "Java"}
extra_skills = student_skills - required_skills
print(extra_skills)
Result:
Output:
{'Java'}
Symmetric Difference
Symmetric difference finds values that exist in only one of the sets, but not both.
Use ^ or symmetric_difference().
required_skills = {"Python", "SQL", "Git"}
student_skills = {"Python", "SQL", "Java"}
different_skills = student_skills ^ required_skills
print(different_skills)
Result contains:
Output:
{'Java', 'Git'}
Python and SQL are not included because they are common to both sets.
Set Operations Comparison
Using:
student_skills = {"Python", "SQL", "Java"}
print(required_skills = {"Python", "SQL", "Git"})
| Operation | Symbol | Meaning | Result |
|---|---|---|---|
| Union | \| |
All unique skills | Python, SQL, Java, Git |
| Intersection | & |
Common skills | Python, SQL |
| Difference | - |
Skills in first set only | Java |
| Symmetric Difference | ^ |
Skills not common | Java, Git |
Visual Understanding
Output:
Student Skills = Python, SQL, Java
Required Skills = Python, SQL, Git
Union → Python, SQL, Java, Git
Intersection → Python, SQL
Student - Required → Java
Required - Student → Git
Symmetric Difference → Java, Git
Subset
A set is a subset if all its elements exist in another set.
student_skills = {"Python", "SQL", "Java"}
basic_skills = {"Python", "SQL"}
print(basic_skills.issubset(student_skills))
Output:
True
All basic_skills exist in student_skills.
Using the operator:
student_skills = {"Python", "SQL", "Java"}
basic_skills = {"Python", "SQL"}
print(basic_skills <= student_skills)
Superset
A set is a superset if it contains all elements of another set.
basic_skills = {"Python", "SQL"}
student_skills = {"Python", "SQL", "Java"}
print(student_skills.issuperset(basic_skills))
Output:
True
Using the operator:
basic_skills = {"Python", "SQL"}
student_skills = {"Python", "SQL", "Java"}
print(student_skills >= basic_skills)
Subset vs Superset
| Concept | Meaning |
|---|---|
| Subset | All my elements exist in another set |
| Superset | I contain all elements of another set |
Output:
True
Disjoint Sets
Two sets are disjoint if they have no common elements.
student_skills = {"Python", "SQL"}
design_skills = {"Figma", "Photoshop"}
print(student_skills.isdisjoint(design_skills))
Output:
True
There are no common skills.
Set Copying
Consider:
student_skills = {"Python", "SQL"}
new_skills = student_skills
This does not create an independent set.
student_skills = {"Python", "SQL"}
new_skills = student_skills
new_skills.add("Java")
print(student_skills)
The original set also changes.
Use copy().
student_skills = {"Python", "SQL"}
new_skills = student_skills.copy()
new_skills.add("Java")
print(student_skills)
print(new_skills)
The sets are now separate.
Common Set Methods
| Method | Purpose |
|---|---|
add() |
Add one element |
update() |
Add elements from an iterable |
remove() |
Remove value; error if missing |
discard() |
Remove value safely |
pop() |
Remove an arbitrary element |
clear() |
Remove all elements |
union() |
Combine unique values |
intersection() |
Find common values |
difference() |
Find values in the first set only |
symmetric_difference() |
Find non-common values |
issubset() |
Check subset |
issuperset() |
Check superset |
isdisjoint() |
Check for no common values |
copy() |
Create a shallow copy |
Common Fresher Mistakes
| ✗ Mistake | Problem | ✓ Correct Understanding |
|---|---|---|
{} used for empty set |
Creates a dictionary | Use set() |
skills[0] |
Sets do not support indexing | Use membership checks or iteration |
| Expecting set output order | Sets are unordered | Do not rely on display order |
remove() on a missing value |
Raises KeyError |
Use discard() when absence is acceptable |
| Expecting duplicates | Sets store unique values | Duplicate values are removed |
Thinking pop() removes the last item |
Set has no positional last item | pop() removes an arbitrary element |
b = a expecting a copy |
Both refer to the same set | Use a.copy() |
Practical Example — Placement Skill Gap Checker
student_skills = {"Python", "SQL", "Java"}
required_skills = {"Python", "SQL", "Git"}
common_skills = student_skills & required_skills
missing_skills = required_skills - student_skills
extra_skills = student_skills - required_skills
print("Matched Skills:", common_skills)
print("Missing Skills:", missing_skills)
print("Extra Skills:", extra_skills)
Possible output:
Matched Skills: {'Python', 'SQL'}
Missing Skills: {'Git'}
Extra Skills: {'Java'}
This same logic can be used in:
- Resume matching
- Job skill matching
- Permission comparison
- Tag comparison
- Recommendation systems
- Data deduplication
Placement Quick Points
- A set stores unique values.
- Sets are unordered.
- Sets are mutable.
- Sets do not support indexing.
- Use
set()to create an empty set. {}creates an empty dictionary.add()adds one element.update()adds elements from an iterable.remove()raisesKeyErrorif the value is missing.discard()does not raise an error for a missing value.- Union combines unique values.
- Intersection finds common values.
- Difference finds values present only in the first set.
- Symmetric difference finds non-common values.
inis commonly used for membership checking.pop()removes an arbitrary element.
Interview Questions
- What is a set in Python?
- A set is an unordered collection of unique elements.
- Does a set allow duplicate values?
- No.
- Does a set support indexing?
- No.
- How do you create an empty set?
data = set().- What does
{}create? - An empty dictionary.
- What is the difference between
add()andupdate()? add()adds one element.update()adds elements from an iterable.- What is the difference between
remove()anddiscard()? remove()raisesKeyErrorif the value is missing.discard()does not.- What is union?
- It combines all unique elements from both sets.
- What is intersection?
- It returns common elements.
- What is difference?
- It returns elements present in the first set but not the second.
- What is symmetric difference?
- It returns elements that are not common to both sets.
- What does
pop()remove from a set? - An arbitrary element.
- What is a subset?
- A set whose every element exists in another set.
- What are disjoint sets?
- Sets with no common elements.
Practice
Use:
student_skills = {"Python", "SQL", "Java"}
required_skills = {"Python", "SQL", "Git"}
- Add
"Git"tostudent_skills. - Add
"HTML"and"CSS"usingupdate(). - Check whether
"Python"exists. - Remove
"Java"usingremove(). - Safely remove
"C++"usingdiscard(). - Find all unique skills from both sets.
- Find common skills.
- Find the student's missing skills.
- Find the student's extra skills.
- Find the symmetric difference.
- Check whether
{"Python", "SQL"}is a subset ofstudent_skills. - Create an empty set.
- Explain why
{}is not an empty set. - Find the error:
print(student_skills[0])
- Explain the difference:
student_skills = {"Python", "SQL", "Java"}
student_skills.remove("C++")
student_skills.discard("C++")
Dictionaries
What is a Dictionary?
A dictionary is a collection used to store data as key-value pairs.
student = {
"name": "Arun",
"age": 21,
"department": "CSE",
"cgpa": 8.5,
"is_placed": False
print(})
Here:
"name"is a key"Arun"is its value
Output:
"name" → "Arun"
"age" → 21
"cgpa" → 8.5
Why Do We Use Dictionaries?
Consider a student profile stored using a list:
student = ["Arun", 21, "CSE", 8.5, False]
What does 8.5 represent?
We need to remember its position.
Using a dictionary:
student = {
"name": "Arun",
"age": 21,
"department": "CSE",
"cgpa": 8.5,
"is_placed": False
}
Now the data has a clear meaning.
student = {
student["cgpa"] # 8.5
Dictionaries make structured data easy to understand and access.
Real-Time Usage
Dictionaries are commonly used to represent structured data.
Examples:
- User profiles
- Student records
- API responses
- JSON-like data
- Product details
- Application configuration
- Database records
- Model results
Example API-style user data:
user = {
"id": 101,
"name": "Arun",
"email": "arun@gmail.com",
"is_active": True
}
Key Features of Dictionaries
| Feature | Meaning |
|---|---|
| Key-Value Pairs | Stores data as key: value |
| Ordered | Maintains insertion order |
| Mutable | Values can be changed |
| Unique Keys | Duplicate keys are not allowed as separate entries |
| Dynamic | Items can be added or removed |
| Key-Based Access | Values are accessed using keys |
Creating a Dictionary
We will use the same student dictionary throughout this topic.
student = {
"name": "Arun",
"age": 21,
"department": "CSE",
"cgpa": 8.5,
"is_placed": False
}
Empty Dictionary
student = {}
Accessing Dictionary Values
Dictionary values are accessed using keys.
student = {}
print(student = {}
student = {}
student = {"name": "Arun", "cgpa": 8.5}
student["name"])
print(student["department"])
print(student["cgpa"])
Output:
Arun
CSE
8.5
Unlike lists, dictionaries do not use positional indexes for normal access.
student = {}
student[0] # KeyError
We access values using keys.
student["name"]
Accessing Values Using get()
The get() method is another way to access a value.
student = {}
print(student.get("name"))
Output:
None
[] vs get()
What happens when a key does not exist?
Using []:
student = {}
print(student["email"])
Error:
Output:
KeyError: 'email'
Using get():
student = {}
print(student.get("email"))
Output:
None
We can also provide a default value.
student = {}
print(student.get("email", "Not Available"))
Output:
Not Available
[] vs get() Comparison
| Access Method | Missing Key |
|---|---|
student["email"] |
Raises KeyError |
student.get("email") |
Returns None |
student.get("email", "Not Available") |
Returns default value |
Placement Favorite: Difference between [] and get().
Updating a Value
Dictionaries are mutable.
We can change an existing value.
student = {}
student = {}
student = {}
student["cgpa"] = 9.0
print(student["cgpa"])
Output:
9.0
Let's update the placement status.
student = {}
student["is_placed"] = True
print(student["is_placed"])
Output:
True
Adding a New Key-Value Pair
Assign a value to a new key.
student = {}
student = {}
student = {}
student["email"] = "arun@gmail.com"
Now the dictionary contains:
{
"name": "Arun",
"age": 21,
"department": "CSE",
"cgpa": 9.0,
"is_placed": True,
"email": "arun@gmail.com"
}
Important Rule
student["cgpa"] = 9.0
Existing key → updates the value
student["email"] = "arun@gmail.com"
New key → adds a new key-value pair
Updating Multiple Values Using update()
The update() method can add or update multiple values.
student = {}
student.update({
"cgpa": 9.2,
"is_placed": True
})
Now:
student = {}
print(student["cgpa"]) # 9.2
print(student["is_placed"]) # True
Adding vs Updating
| Operation | Example | Result |
|---|---|---|
| Existing key | student["cgpa"] = 9.0 |
Updates value |
| New key | student["email"] = "arun@gmail.com" |
Adds new item |
update() |
student.update({...}) |
Adds or updates items |
Removing Dictionary Items
pop()
Removes a key and returns its value.
student = {}
removed = student.pop("age")
print(removed)
Output:
21
The "age" key is removed from the dictionary.
popitem()
Removes and returns the last inserted key-value pair.
student = {}
item = student.popitem()
print(item)
del
Deletes a specific key-value pair.
student = {}
del student["department"]
clear()
Removes all items.
student = {}
student.clear()
print(student)
Output:
{}
Dictionary Removal Methods
| Method | Purpose |
|---|---|
pop(key) |
Removes a specific key and returns its value |
popitem() |
Removes the last inserted item |
del |
Deletes a specific key |
clear() |
Removes all items |
Getting Keys, Values, and Items
Let's use our student dictionary:
student = {
"name": "Arun",
"age": 21,
"department": "CSE",
"cgpa": 8.5,
"is_placed": False
}
keys()
Returns all keys.
student = {
print(student.keys())
Output:
dict_keys(['name', 'age', 'department', 'cgpa', 'is_placed'])
values()
Returns all values.
student = {
print(student.values())
Output:
dict_values(['Arun', 21, 'CSE', 8.5, False])
items()
Returns key-value pairs.
student = {
print(student.items())
Each item is represented as a (key, value) pair.
keys() vs values() vs items()
| Method | Returns |
|---|---|
keys() |
Keys |
values() |
Values |
items() |
Key-value pairs |
Checking if a Key Exists
Use the in operator.
student = {
print("name" in student) # True
print("email" in student) # False
By default, in checks dictionary keys.
student = {
"Arun" in student # False
To check values:
student = {
"Arun" in student.values() # True
Looping Through a Dictionary
Loop Through Keys
student = {
for key in student:
print(key)
Loop Through Values
student = {
for value in student.values():
print(value)
Loop Through Key-Value Pairs
student = {
for key, value in student.items():
print(key, ":", value)
Output:
name : Arun
age : 21
department : CSE
cgpa : 8.5
is_placed : False
Recommended: Use items() when both key and value are required.
Duplicate Keys
Dictionary keys must be unique.
student = {
"name": "Arun",
"name": "Kumar"
}
print(student)
Output:
{'name': 'Kumar'}
The latest value replaces the previous value for the same key.
Dictionary Keys
Dictionary keys must be hashable.
Common valid key types:
data = {
"name": "Arun",
1: "First",
(10, 20): "Coordinates"
}
Common invalid key:
data = {
[1, 2]: "Numbers"
}
This raises a TypeError because a list cannot be used as a dictionary key.
Beginner Rule
Use immutable, hashable values such as:
strintfloat- suitable
tuplevalues
as dictionary keys.
Nested Dictionary
Real applications often contain nested dictionaries.
Let's extend our student example.
student = {
"name": "Arun",
"age": 21,
"department": "CSE",
"cgpa": 8.5,
"is_placed": False,
"address": {
"city": "Chennai",
"state": "Tamil Nadu"
}
}
Access the city:
student = {
print(student = {
student = {
student = {
student = {
student = {"name": "Arun", "cgpa": 8.5}
student = {"name": "Arun", "cgpa": 8.5}
student["address"]["city"])
Output:
Chennai
How It Works
student["address"]
Returns:
{
"city": "Chennai",
"state": "Tamil Nadu"
}
Then:
student["address"]["city"]
Returns:
Output:
Chennai
Dictionary Copying
Consider:
student = {
student_copy = student
This does not create an independent dictionary. Both names refer to the same dictionary.
student_copy = student
student_copy["cgpa"] = 9.5
print(student["cgpa"])
Output:
9.5
Use copy():
student = {
student_copy = student.copy()
Now the outer dictionary is copied separately.
Shallow copy and deep copy are covered separately in the Copying Objects topic.
Common Dictionary Methods
| Method | Purpose |
|---|---|
get() |
Safely access a value |
keys() |
Get all keys |
values() |
Get all values |
items() |
Get key-value pairs |
update() |
Add or update items |
pop() |
Remove a specific key |
popitem() |
Remove the last inserted item |
copy() |
Create a shallow copy |
clear() |
Remove all items |
Common Fresher Mistakes
| ✗ Mistake | Problem | ✓ Correct Understanding |
|---|---|---|
student[0] |
Dictionary is not accessed by position | Use student["name"] |
student["email"] for a missing key |
Raises KeyError |
Use student.get("email") |
| Thinking duplicate keys are stored separately | Keys must be unique | Latest value replaces old value |
"Arun" in student expecting True |
in checks keys |
Use "Arun" in student.values() |
copy = student expecting a copy |
Both refer to the same dictionary | Use student.copy() |
| Using a list as a key | Lists are unhashable | Use a suitable immutable key |
Practical Example — Student Placement Profile
student = {
"name": "Arun",
"age": 21,
"department": "CSE",
"cgpa": 8.5,
"is_placed": False
}
student["skills"] = ["Python", "SQL"]
student["cgpa"] = 9.0
student["is_placed"] = True
print("Student Name:", student["name"])
print("CGPA:", student["cgpa"])
print("Skills:", student["skills"])
print("Placement Status:", student["is_placed"])
Output:
Student Name: Arun
CGPA: 9.0
Skills: ['Python', 'SQL']
Placement Status: True
This is similar to how structured records are handled in real applications.
Placement Quick Points
- A dictionary stores data as key-value pairs.
- Dictionaries are mutable.
- Dictionary keys must be unique.
- Values are accessed using keys.
[]raisesKeyErrorfor a missing key.get()safely handles missing keys.- Assigning to an existing key updates its value.
- Assigning to a new key adds a new item.
update()adds or updates multiple items.inchecks dictionary keys by default.items()provides key-value pairs.pop()removes a key and returns its value.- Duplicate keys are overwritten by the latest value.
- Dictionary keys must be hashable.
Interview Questions
- What is a dictionary in Python?
- A dictionary is a mutable collection that stores data as key-value pairs.
- Are dictionary keys unique?
- Yes.
- Can dictionary values be duplicated?
- Yes.
- What is the difference between
[]andget()? []raisesKeyErrorfor a missing key.get()returnsNoneor a default value.- What does the
inoperator check in a dictionary? - Keys.
- What is the difference between
keys(),values(), anditems()? keys()returns keys,values()returns values, anditems()returns key-value pairs.- What happens when a duplicate key is used?
- The latest value replaces the previous value.
- Can a list be used as a dictionary key?
- No. Lists are unhashable.
- Is a dictionary mutable?
- Yes.
- How do you safely access a missing key?
student.get("email").- What is a nested dictionary?
- A dictionary containing another dictionary as a value.
- Does
b = acopy a dictionary? - No. Both names refer to the same dictionary.
Practice
Use this dictionary:
student = {
"name": "Arun",
"age": 21,
"department": "CSE",
"cgpa": 8.5,
"is_placed": False
}
- Print the student's name.
- Print the CGPA using
get(). - Add an
"email"key. - Update the CGPA to
9.0. - Change
is_placedtoTrue. - Check whether
"department"exists. - Print all keys.
- Print all values.
- Print all key-value pairs.
- Remove the
"age"key usingpop(). - Loop through the dictionary using
items(). - Create a copy of the student dictionary.
- Add an
"address"nested dictionary. - Access the city from the nested dictionary.
- Explain the output:
student = {
print(student.get("phone"))
- Explain the difference:
student = {
student["phone"]
student.get("phone")
End of Level 3