UNIT-2
PYTHON
Strings as Arrays in Python
In Python, strings are sequences of characters, and each character in a string can be accessed using indexing,
just like elements in an array or list.
Strings are immutable arrays — you can access characters but cannot modify them in-place.
Key Concepts
Concept Example
Indexing Access individual characters
Negative indexing Access from the end
Slicing Extract substring using range
Iterating Loop through each character
1. Indexing
Each character in a string has a position (index), starting from 0.
text = "Python"
print(text[0]) # Output: 'P'
print(text[1]) # Output: 'y'
print(text[5]) # Output: 'n'
Index positions:
Python
012345
2. Negative Indexing
You can also index from the end using negative numbers:
text = "Python"
print(text[-1]) # Output: 'n' (last character)
print(text[-2]) # Output: 'o'
Negative index positions:
Python
-6 -5 -4 -3 -2 -1
3. Slicing Strings
You can extract parts of a string using slicing: string[start:end]
(End index is exclusive.)
text = "Python"
print(text[0:4]) # 'Pyth'
print(text[:3]) # 'Pyt' (from start to index 2)
print(text[3:]) # 'hon' (from index 3 to end)
4. Iterating Over Strings
You can loop through a string just like an array:
text = "Hi!"
for char in text:
print(char)
Output:
5. Strings Are Immutable
You cannot modify characters directly:
text = "Hello"
# text[0] = "J" ❌ This will raise an error!
✅ Instead, create a new string:
text = "Hello"
new_text = "J" + text[1:]
print(new_text) # 'Jello'
What is a Regular Expression?
A regular expression (regex) is a pattern used to match, search, replace, and validate strings.
To use regular expressions in Python, we import the re module:
import re
Common Regex Functions in Python
Function Description
[Link]() Searches for the first match
[Link]() Returns a list of all matches
[Link]() Checks match at beginning of string
[Link]() Replaces occurrences with something else
[Link]() Splits string by regex pattern
Example String:
text = "My phone is 9876543210 and email is test@[Link]"
1. [Link]() – Search for a pattern
match = [Link](r'\d+', text) # \d+ means one or more digits
print([Link]()) # Output: 9876543210
2. [Link]() – Find all matches
emails = [Link](r'\S+@\S+', text)
print(emails) # Output: ['test@[Link]']
3. [Link]() – Match at the beginning
if [Link](r"My", text):
print("Starts with 'My'")
4. [Link]() – Replace patterns
masked = [Link](r'\d+', 'XXXXXXXXXX', text)
print(masked) # My phone is XXXXXXXXXX and email is test@[Link]
5. [Link]() – Split string by pattern
words = [Link](r'\s+', text)
print(words) # ['My', 'phone', 'is', '9876543210', ...]
Useful Regex Patterns
Pattern Description Example Match
\d Digit (0–9) 123
\w Word character (letters, digits) Hello123
\s Whitespace (space, tab, newline) ''
. Any character (except newline) a, b, 1
^ Start of string ^Hello
$ End of string world$
* 0 or more lo* matches l, loo
+ 1 or more lo+ matches lo, loo
? 0 or 1 colou?r matches color, colour
[...] Set of characters [aeiou] matches vowels
` ` OR
() Group (abc)+
Example: Validate an Email
email = "test123@[Link]"
pattern = r'^[\w\.-]+@[\w\.-]+\.\w+$'
if [Link](pattern, email):
print("Valid email")
else:
print("Invalid email")
String Concatenation (Joining Strings)
Concatenation means combining strings together.
Methods:
A. Using + operator
first = "Hello"
second = "World"
result = first + " " + second
print(result) # Hello World
B. Using join() (more efficient for many strings)
words = ["Python", "is", "awesome"]
sentence = " ".join(words)
print(sentence) # Python is awesome
C. Using f-strings
name = "Alice"
greeting = f"Hello, {name}!"
print(greeting) # Hello, Alice!
D. Using format()
greeting = "Hello, {}!".format("Bob")
print(greeting) # Hello, Bob!
String Modification (Changing contents)
Python strings are immutable — but you can create a modified copy using built-in methods.
Examples:
text = " hEllO WoRLd "
print([Link]()) # Removes spaces -> 'hEllO WoRLd'
print([Link]()) # All lowercase -> ' hello world '
print([Link]()) # All uppercase -> ' HELLO WORLD '
print([Link]()) # First letter capital -> ' hello world '
print([Link]()) # Title case -> ' Hello World '
print([Link]()) # Swap case -> ' HeLLo wOrlD '
print([Link]("WoRLd", "Python")) # Replace word
String Searching
Python offers several methods to find substrings in a string.
Examples:
text = "Hello, welcome to Python programming."
print("Python" in text) # True
print([Link]("Python")) # 18 (index where found)
print([Link]("Python")) # 18 (like find, but error if not found)
print([Link]("Hello")) # True
print([Link]("programming.")) # True
Difference between find() and index()
• find() returns -1 if not found.
• index() raises a ValueError.
String Sorting
Sorting strings means arranging characters or list of strings alphabetically.
A. Sorting characters in a string:
text = "banana"
sorted_chars = sorted(text)
print("".join(sorted_chars)) # aaabnn
B. Sorting a list of strings:
fruits = ["banana", "apple", "cherry"]
[Link]()
print(fruits) # ['apple', 'banana', 'cherry']
C. Case-insensitive sorting:
names = ["Alice", "bob", "Charlie"]
[Link](key=[Link])
print(names) # ['Alice', 'bob', 'Charlie']
List
What is a List?
A list is a collection that is:
• Ordered
• Mutable (can be changed)
• Can contain different data types
• Can have duplicates
Example:
my_list = [10, "hello", 3.14, True]
Creating a List
# Empty list
empty = []
# List of integers
numbers = [1, 2, 3, 4]
# Mixed data types
mixed = ["Alice", 25, 5.5, False]
# Nested list
nested = [[1, 2], [3, 4]]
Accessing Elements
fruits = ["apple", "banana", "cherry"]
print(fruits[0]) # apple
print(fruits[-1]) # cherry (last element)
print(fruits[1:3]) # ['banana', 'cherry']
Adding Elements
• append() – Adds to end
[Link]("orange")
print(fruits) # ['apple', 'banana', 'cherry', 'orange']
• insert(index, value) – Adds at index
[Link](1, "grape")
print(fruits) # ['apple', 'grape', 'banana', 'cherry', 'orange']
• extend() – Adds another list
[Link](["kiwi", "melon"])
print(fruits) # ['apple', 'grape', ..., 'melon']
Removing Elements
• remove(value)
[Link]("banana")
print(fruits) # Removes first 'banana'
• pop(index) – Removes by index
last = [Link]()
print(last) # 'melon'
• clear() – Removes all
[Link]()
print(fruits) # []
Slicing a List
numbers = [10, 20, 30, 40, 50, 60]
print(numbers[1:4]) # [20, 30, 40]
print(numbers[:3]) # [10, 20, 30]
print(numbers[::2]) # [10, 30, 50]
print(numbers[::-1]) # [60, 50, 40, 30, 20, 10]
List Concatenation and Repetition
a = [1, 2]
b = [3, 4]
print(a + b) # [1, 2, 3, 4]
print(a * 3) # [1, 2, 1, 2, 1, 2]
Sorting a List
sort() – Sort in-place
nums = [5, 2, 8, 1]
[Link]()
print(nums) # [1, 2, 5, 8]
sorted() – Returns a new sorted list
nums = [4, 9, 3]
sorted_nums = sorted(nums)
print(sorted_nums) # [3, 4, 9]
Sort descending
[Link](reverse=True)
Useful List Functions
marks = [80, 90, 70, 90]
print(len(marks)) # 4
print(min(marks)) # 70
print(max(marks)) # 90
print(sum(marks)) # 330
print([Link](90)) # 2
print([Link](70)) # 2
Looping Through a List
colors = ["red", "green", "blue"]
for color in colors:
print(color)
List Comprehension
squares = [x**2 for x in range(1, 6)]
print(squares) # [1, 4, 9, 16, 25]
Tuple
What is a Tuple?
A tuple is:
• An ordered, immutable collection
• Allows duplicate values
• Elements can be of different data types
Key difference from lists:
• Tuples cannot be changed after creation (immutable)
• Tuples are generally faster and memory-efficient
Creating Tuples
# Empty tuple
t1 = ()
# Tuple of integers
t2 = (1, 2, 3)
# Mixed data types
t3 = ("Alice", 25, 5.5, True)
# Nested tuples
t4 = ((1, 2), (3, 4))
# Without parentheses
t5 = 10, 20, 30
# Single-element tuple (must have a comma!)
t6 = (5,)
🔸 Accessing Elements
Tuples are indexed like lists.
t = ("apple", "banana", "cherry")
print(t[0]) # apple
print(t[-1]) # cherry
print(t[1:]) # ('banana', 'cherry')
🔸 Tuple is Immutable
You cannot change or delete items in a tuple.
t = (1, 2, 3)
# t[1] = 10 ❌ Error: 'tuple' object does not support item assignment
# del t[0] ❌ Error: 'tuple' object doesn't support item deletion
However, you can delete the entire tuple:
del t
Tuple Operations
Concatenation (+)
a = (1, 2)
b = (3, 4)
c=a+b
print(c) # (1, 2, 3, 4)
Repetition (*)
print(a * 3) # (1, 2, 1, 2, 1, 2)
Membership Test (in)
print(2 in a) # True
print(5 not in a) # True
Tuple Functions
Function Description
len(t) Number of items
min(t) Minimum value (numeric/char)
max(t) Maximum value
sum(t) Sum of all numeric elements
[Link](x) Position of first occurrence of x
[Link](x) Number of times x appears
t = (1, 2, 3, 2, 4)
print(len(t)) # 5
print([Link](2)) # 2
print([Link](3)) # 2
Tuple Packing and Unpacking
Packing
person = ("Alice", 25, "Engineer")
Unpacking
name, age, job = person
print(name) # Alice
Tuples vs Lists
Feature List Tuple
Syntax [1, 2, 3] (1, 2, 3)
Mutable ✅ Yes ❌ No
Performance Slower Faster
Use case Dynamic data Fixed/constant
When to Use Tuples?
• When you want to protect data from being changed
• To store fixed sets (e.g., coordinates, RGB values)
• As keys in dictionaries (only hashable types can be keys)
• When performance matters (tuples are slightly faster)
Tuple Inside List / List Inside Tuple
# List of tuples
students = [("Alice", 24), ("Bob", 22)]
# Tuple of lists
scores = ([80, 90], [70, 85])
Dictionary
What is a Dictionary?
A dictionary is a collection of key-value pairs in Python.
Each key maps to a value, similar to a real-world dictionary (e.g., "name" → "John").
Characteristics:
Feature Description
Ordered (3.7+) Maintains insertion order.
Mutable You can change, add, or remove items.
Key uniqueness Keys must be unique and immutable (e.g., string, int, tuple).
Fast access Accessing by key is very fast (O(1) average time).
Creating a Dictionary
Syntax:
dictionary_name = {
"key1": "value1",
"key2": "value2"
Examples:
# Empty dictionary
empty_dict = {}
# Dictionary with data
person = {"name": "Alice", "age": 25, "country": "India"}
# Using dict() constructor
info = dict(name="John", age=30, city="New York")
Accessing Items
Example:
print(person["name"]) # Alice
print([Link]("age")) # 25
print([Link]("email")) # None (avoids error if key not found)
.get(key, default) is safer than using [].
Adding & Updating Items
Example:
person["email"] = "alice@[Link]" # Adds new key
person["age"] = 26 # Updates age
Removing Items
Different ways to remove:
# Remove key-value pair
del person["country"]
# Remove and get value
email = [Link]("email")
# Remove last inserted item (3.7+)
[Link]()
# Remove all items
[Link]()
Dictionary Methods (with Examples)
Method Description Example
.get(key) Returns value or None [Link]("name")
.keys() Returns all keys for k in [Link]()
.values() Returns all values for v in [Link]()
.items() Returns key-value pairs as tuples for k,v in [Link]()
.update(d2) Adds/updates from another dictionary [Link](d2)
.pop(key) Removes and returns value of key val = [Link]("name")
.popitem() Removes and returns last key-value pair [Link]()
.clear() Empties the dictionary [Link]()
.get(key)
Description:
Returns the value for the specified key if it exists; otherwise, it returns None.
You can also provide a default value if the key is not found.
Example:
person = {"name": "Alice", "age": 25}
print([Link]("name")) # Alice
print([Link]("email")) # None (doesn't raise error)
print([Link]("email", "N/A")) # N/A (custom default)
Why use .get()?
Avoids KeyError if the key doesn't exist.
Good for safe key access.
2. keys()
Description:
Returns a view object that displays a list of all the keys in the dictionary.
Example:
person = {"name": "Bob", "age": 30}
for key in [Link]():
print(key)
Output:
name
age
You can convert the result to a list using list([Link]()).
3. values()
Description:
Returns a view object containing all the values in the dictionary.
Example:
person = {"name": "Bob", "age": 30}
for value in [Link]():
print(value)
Output:
Bob
30
4. items()
Description:
Returns a view object containing (key, value) pairs as tuples.
Example:
person = {"name": "Bob", "age": 30}
for key, value in [Link]():
print(key, "->", value)
Output:
name -> Bob
age -> 30
Use Case:
Great for looping through both keys and values in one go.
5. update(other_dict)
Description:
Updates the dictionary with the key-value pairs from another dictionary.
If keys overlap, values from other_dict will overwrite the existing ones.
Example:
a = {"x": 1, "y": 2}
b = {"y": 3, "z": 4}
[Link](b)
print(a)
🖨 Output:
{'x': 1, 'y': 3, 'z': 4}
Use Case:
Merging dictionaries or updating specific keys.
6. .pop(key)
Description:
Removes the specified key from the dictionary and returns its value.
Example:
person = {"name": "Alice", "age": 25}
age = [Link]("age")
print(age) # 25
print(person) # {'name': 'Alice'}
Raises KeyError if the key doesn’t exist, unless a default is provided:
[Link]("email", "Not Found") # Safe
Looping Through Dictionary
student = {"name": "Ravi", "marks": 90}
# Loop through keys
for key in student:
print(key, "->", student[key])
# Loop through key-value pairs
for key, value in [Link]():
print(f"{key}: {value}")
Dictionary Comprehension
A compact way to build a dictionary.
# Square of numbers from 1 to 5
squares = {x: x**2 for x in range(1, 6)}
print(squares)
Nested Dictionary
A dictionary containing another dictionary.
students = {
"101": {"name": "Anu", "marks": 88},
"102": {"name": "Raj", "marks": 91}
print(students["101"]["name"]) # Anu
Sets
What is a Set in Python?
A set is an unordered, unindexed collection of unique elements.
key Properties:
Feature Description
Unordered No guaranteed order of elements
No duplicates Automatically removes duplicates
Mutable You can add or remove items
Set operations Supports union, intersection, difference, etc.
Creating a Set
Using Curly Braces {}:
my_set = {1, 2, 3, 4}
print(my_set) # {1, 2, 3, 4}
Using set() constructor:
s = set([1, 2, 2, 3])
print(s) # {1, 2, 3} – duplicates removed
Empty set must use set(), not {}:
a = set() # ✅ empty set
b = {} # ❌ creates an empty dictionary
Accessing Set Items
• Sets are unordered, so you can’t access elements by index.
• You can loop through them:
for item in my_set:
print(item)
Adding Elements
.add(element)
s = {1, 2}
[Link](3)
print(s) # {1, 2, 3}
Updating Sets with Multiple Elements
update(iterable)
s = {1, 2}
[Link]([3, 4, 5])
print(s) # {1, 2, 3, 4, 5}
Removing Elements
Method Description Error on Missing Element?
.remove(x) Removes x; raises error if missing ❌ Yes
.discard(x) Removes x; does nothing if missing ✅ No
.pop() Removes and returns random element ✅ Yes
.clear() Empties the set completely ✅ No
Examples:
s = {1, 2, 3}
[Link](2) # Removes 2
[Link](10) # Does nothing (no error)
x = [Link]() # Removes random element
[Link]() # Empties the set
Set Operations
Python supports set theory operations:
Union – .union() or |
Combines all elements (no duplicates).
a = {1, 2}
b = {2, 3}
print(a | b) # {1, 2, 3}
print([Link](b)) # {1, 2, 3}
Intersection – .intersection() or &
Only elements present in both sets.
print(a & b) # {2}
print([Link](b)) # {2}
Difference – .difference() or -
Items in the first set not in the second.
print(a - b) # {1}
print(b - a) # {3}
Symmetric Difference – .symmetric_difference() or ^
Items in either set, but not both.
print(a ^ b) # {1, 3}
Set Comparisons
Comparison Description
a == b Checks if sets are equal
[Link](b) Checks if a is a subset of b
[Link](b) Checks if a is a superset of b
[Link](b) True if sets have no elements in common
Built-in Set Functions
Function Description
len(s) Number of elements in set
max(s) Maximum element
min(s) Minimum element
sorted(s) Returns sorted list of elements
Function Description
sum(s) Sum of all numeric elements
Feature List Tuple Set Dictionary
Ordered ✅ Yes ✅ Yes ❌ No ✅ Yes (from Python 3.7+)
Mutable ✅ Yes ❌ No ✅ Yes ✅ Yes
Duplicates ✅ Allowed ✅ Allowed ❌ Not allowed ❌ Keys ❌, Values ✅
Indexing ✅ By number ✅ By number ❌ Not supported ✅ By key
Syntax [] () {} {key: value}
Use Case General items Fixed/read-only Unique items Lookup by name/label
Data Type Insertion Methods Removal Methods
List append(item) → add to end remove(item) → remove first occurrence
insert(index, item) → insert at position pop() → remove last item
extend(iterable) → add multiple items pop(index) → remove item at index
clear() → remove all items
Tuple ❌ Immutable – no direct insertion ❌ Immutable – no direct removal
✅ Workaround: convert to list, modify, then
convert back
tuple(list(my_tuple) + [new_item])
remove(item) → remove item (error if not
Set add(item) → add a single item
found)
discard(item) → remove item (no error if
update(iterable) → add multiple items
not found)
pop() → remove random item
clear() → remove all items
Dictionary dict[key] = value → add/update key-value pair pop(key) → remove by key
Data Type Insertion Methods Removal Methods
update({key: value}) → add/update multiple keys popitem() → remove last inserted pair
del dict[key] → delete specific key
clear() → remove all key-value pairs