0% found this document useful (0 votes)
3 views32 pages

Python -Module2 (1)

These Python course notes provide an in-depth reference on strings and lists, covering key concepts, methods, and examples for both data types. The document is structured into three main parts: Strings, Lists, and Quick Reference Tables, detailing operations such as indexing, slicing, and string manipulation techniques. Mastery of these topics is essential for becoming proficient in Python programming.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views32 pages

Python -Module2 (1)

These Python course notes provide an in-depth reference on strings and lists, covering key concepts, methods, and examples for both data types. The document is structured into three main parts: Strings, Lists, and Quick Reference Tables, detailing operations such as indexing, slicing, and string manipulation techniques. Mastery of these topics is essential for becoming proficient in Python programming.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Python Course Notes – Strings & Lists

Python Course Notes


Strings & Lists – In-Depth Reference
Comprehensive notes with detailed explanations and coding examples

Table of Contents
PART 1: STRINGS
1.1 Introduction to Strings
1.2 Working with Strings
1.3 String Literals
1.4 Indexes and Slices
1.5 in and not in Operators
1.6 F-Strings
1.7 Useful String Methods
PART 2: LISTS
2.1 Introduction to Lists
2.2 List Indexes
2.3 Negative Indexes
2.4 Slices
2.5 len() Function
2.6 Updating Values
2.7 Concatenation and Replication
2.8 del Statement
2.9 Working with Lists
2.10 for Loops and Lists
2.11 in and not in with Lists
2.12 Multiple Assignment
2.13 List Methods
PART 3: QUICK REFERENCE TABLES

PART 1 — STRINGS
Strings are one of the most fundamental and frequently used data types in Python. Nearly every real-
world Python program uses strings extensively — for user input, file operations, web scraping, data
processing, and much more. Mastering strings is essential to becoming a proficient Python
programmer.

Page 1
Python Course Notes – Strings & Lists

1.1 Introduction to Strings


A string in Python is a sequence of characters. Characters can be letters, digits, symbols, spaces, or
even emojis. Strings are one of Python's built-in data types and belong to the category of sequence
types — which means every character in a string has a specific position (index).

Key Properties of Python Strings:


• Ordered: Characters maintain a specific left-to-right order.
• Immutable: Once created, a string cannot be modified. Any operation that appears to change a
string actually creates a new string.
• Iterable: You can loop through a string character by character.
• Indexed: Each character can be accessed via its position.

Example 1.1a – Creating and displaying strings


# A simple string
message = "Hello, World!"
print(message)

# String with single quotes


name = 'Alice'
print(name)

# String assigned to a variable


course = "Python Programming"
print(course)

# Checking the type


print(type(message)) # <class "str">
Hello, World!
Alice
Python Programming
<class 'str'>

Example 1.1b – Strings are immutable


s = "Hello"
# s[0] = "J" ← This would cause a TypeError!
# TypeError: "str" object does not support item assignment

# Correct way: create a new string


s = "J" + s[1:]
print(s) # "Jello"
"Jello"
💡 Because strings are immutable, Python can safely share and cache string objects, making them memory-
efficient.

1.2 Working with Strings


Python provides many ways to work with and manipulate strings. In this section we explore the basic
operations: concatenation, repetition, measuring length, and converting other types to strings.

Page 2
Python Course Notes – Strings & Lists

String Concatenation
Concatenation means joining two or more strings together using the + operator.
Example 1.2a – Concatenating strings
first_name = "John"
last_name = "Doe"

# Join with a space in between


full_name = first_name + " " + last_name
print(full_name) # "John Doe"

# Concatenate multiple strings


greeting = "Hello, " + first_name + "! How are you?"
print(greeting)
"John Doe"
"Hello, John! How are you?"

String Repetition
Use the * operator to repeat a string a number of times.
Example 1.2b – Repeating strings
separator = "-" * 30
print(separator) # prints 30 dashes

word = "ha"
laugh = word * 5
print(laugh) # "hahahahaha"

# Useful for formatting output


print("=" * 40)
print(" WELCOME TO PYTHON ")
print("=" * 40)
------------------------------
hahahahaha
========================================
WELCOME TO PYTHON
========================================

Measuring String Length – len()


The len() function returns the total number of characters in a string, including spaces and special
characters.
Example 1.2c – Using len()
city = "Bangalore"
print(len(city)) # 9

sentence = "Hello World"


print(len(sentence)) # 11 (space is counted!)

empty = ""
print(len(empty)) # 0

# Practical: check if password is long enough


password = "mypass123"

Page 3
Python Course Notes – Strings & Lists

if len(password) >= 8:
print("Password length OK")
else:
print("Password too short")
9
11
0
Password length OK

Converting Other Types to Strings – str()


Use str() to convert integers, floats, booleans, or other objects into strings.
Example 1.2d – Type conversion to string
age = 25
price = 99.95
active = True

# Convert to string
age_str = str(age)
price_str = str(price)
active_str= str(active)

print(type(age_str)) # <class "str">


print("Age: " + age_str) # "Age: 25"

# Without str() this would fail:


# print("Age: " + age) ← TypeError!

# Checking: int vs string "25"


print(25 == "25") # False (different types)
print(25 == int("25")) # True
<class 'str'>
"Age: 25"
False
True
💡 Always use str() when concatenating a number with a string, or use f-strings which handle the conversion
automatically.

1.3 String Literals


A string literal is a string value written directly in your source code. Python supports several forms of
string literals, each designed for different situations.

Single and Double Quotes


Both 'single quotes' and "double quotes" create strings. They are completely equivalent. The
main reason to choose one over the other is to avoid having to escape a quote character inside the
string.
Example 1.3a – Single vs double quotes
# Both are identical
s1 = 'Hello'
s2 = "Hello"
print(s1 == s2) # True

Page 4
Python Course Notes – Strings & Lists

# Use double quotes when string contains apostrophes


line1 = "It's a wonderful day" # needs escape
line2 = "It's a wonderful day" # no escape needed
print(line1)

# Use single quotes when string contains double quotes


line3 = 'She said "Hi"'
print(line3)
True
It's a wonderful day
She said "Hi"

Triple-Quoted Strings
Triple quotes (""" or ''') allow strings to span multiple lines. They also preserve newlines and internal
indentation.
Example 1.3b – Multi-line strings with triple quotes
poem = """
Roses are red,
Violets are blue,
Python is great,
And so are you!
"""
print(poem)

# Triple-quoted string for long messages


message = """Dear Student,
Welcome to the Python course.
We hope you enjoy learning!"""
print(message)

# Also used for multi-line docstrings


def greet(name):
"""
This function greets a person by name.
Parameters: name (str)
"""
return f"Hello, {name}!"

Escape Sequences
An escape sequence starts with a backslash \ and lets you include special characters inside a string.
Example 1.3c – Escape sequences
# Newline \n
print("Line 1\nLine 2\nLine 3")

# Tab \t
print("Name:\tAlice")
print("Score:\t95")

# Backslash \\
path = "C:\\Users\\Alice\\Documents"
print(path)

Page 5
Python Course Notes – Strings & Lists

# Quote inside string


print("He said \"Hello\"")
print('It\'s fine')

# Unicode character \u
print("\u2764 Python") # heart symbol
Line 1
Line 2
Line 3
Name: Alice
Score: 95
C:\Users\Alice\Documents
He said "Hello"


It's fine
Python

Raw Strings
Prefix a string with r to create a raw string where backslashes are treated as literal characters, not
escape sequences. This is especially useful for file paths and regular expressions.
Example 1.3d – Raw strings
# Normal string: \n is interpreted as newline
print("Hello\nWorld") # prints on 2 lines

# Raw string: \n is kept as-is


print(r"Hello\nWorld") # prints: Hello\nWorld

# File paths on Windows


path = r"C:\Users\Alice\Desktop\[Link]"
print(path)

# Without raw string you must double every backslash


path2 = "C:\\Users\\Alice\\Desktop\\[Link]"
print(path == path2) # True
⚠️ Raw strings cannot end with an odd number of backslashes. r"path\" is a syntax error.

1.4 Indexes and Slices


Since a string is a sequence of characters, each character is assigned a numeric position called an
index. Python supports both positive (left-to-right) and negative (right-to-left) indexing.

Positive Indexing
Positive indexes start from 0 at the leftmost character and increase to the right.
Example 1.4a – Positive indexing
word = "Python"
# Characters: P y t h o n
# Index: 0 1 2 3 4 5

print(word[0]) # "P" first character


print(word[1]) # "y"
print(word[4]) # "o"
print(word[5]) # "n" last character

Page 6
Python Course Notes – Strings & Lists

# Accessing characters in a loop


for i in range(len(word)):
print(f"Index {i} -> {word[i]}")
"P"
"y"
"o"
"n"
Index 0 -> P
Index 1 -> y
Index 2 -> t
Index 3 -> h
Index 4 -> o
Index 5 -> n

Negative Indexing
Negative indexes count from the right. -1 is the last character, -2 is second-to-last, and so on.
Example 1.4b – Negative indexing
word = "Python"
# Characters: P y t h o n
# Neg Index: -6 -5 -4 -3 -2 -1

print(word[-1]) # "n" last character


print(word[-2]) # "o"
print(word[-6]) # "P" same as word[0]

# Useful: get last character without knowing length


text = "Hello, World!"
print(text[-1]) # "!"
"n"
"o"
"P"
"!"

⚠️ An IndexError is raised if you use an index that is out of range. For a string of length 6, valid indexes are
0–5 (or -1 to -6).

String Slicing
A slice extracts a portion (substring) of a string. The syntax is:
string[start : end : step]
• start – index where the slice begins (inclusive, default = 0)
• end – index where the slice stops (exclusive, default = end of string)
• step – how many characters to skip (default = 1)

Example 1.4c – Basic slicing


s = "Hello, World!"
# Index: 0123456789...

print(s[0:5]) # "Hello" (positions 0,1,2,3,4)


print(s[7:12]) # "World"
print(s[:5]) # "Hello" (omit start → from beginning)

Page 7
Python Course Notes – Strings & Lists

print(s[7:]) # "World!" (omit end → to end)


print(s[:]) # full copy of string

# Extract last 6 characters


print(s[-6:]) # "orld!"

# Extract every other character


print(s[::2]) # "Hlo ol!"
"Hello"
"World"
"Hello"
"World!"
"Hello, World!"
"orld!"
"Hlo ol!"

Example 1.4d – Step parameter and reversing


s = "abcdefghij"

# Step = 2: every 2nd character


print(s[::2]) # "acegi"

# Step = 3: every 3rd character


print(s[::3]) # "adgj"

# Negative step – read backwards


print(s[::-1]) # "jihgfedcba" (reversed)

# Reverse a word (common interview question!)


word = "Python"
reversed_word = word[::-1]
print(reversed_word) # "nohtyP"

# Check if a word is a palindrome


def is_palindrome(w):
return w == w[::-1]

print(is_palindrome("radar")) # True
print(is_palindrome("hello")) # False
"acegi"
"adgj"
"jihgfedcba"
"nohtyP"
True
False
💡
can.
Slices never raise an IndexError even if start or end is out of range — they simply return as much as they

1.5 in and not in Operators


The in and not in operators are membership operators. They check whether a substring exists
somewhere inside a string, returning True or False.

Basic Usage

Page 8
Python Course Notes – Strings & Lists

Example 1.5a – Checking substrings


sentence = "The quick brown fox jumps over the lazy dog"

# Check for a word


print("fox" in sentence) # True
print("cat" in sentence) # False
print("cat" not in sentence) # True

# Case-sensitive!
print("The" in sentence) # True
print("the" in sentence) # True (appears twice)
print("THE" in sentence) # False (uppercase not found)
True
False
True
True
True
False

Practical Uses
Example 1.5b – Practical in/not in usage
# Input validation
email = "alice@[Link]"
if "@" in email and "." in email:
print("Valid email format")
else:
print("Invalid email format")

# Checking for banned words


banned_words = ["spam", "advertisement", "click here"]
message = "This is not spam content"
for word in banned_words:
if word in message:
print(f"Warning: found banned word '{word}'")
break

# Check if string starts with a vowel


def starts_with_vowel(word):
return word[0].lower() in "aeiou"

print(starts_with_vowel("Apple")) # True
print(starts_with_vowel("Banana")) # False

# Check for digits


pin = "1234"
if all(c in "0123456789" for c in pin):
print("Valid PIN")
Valid email format
Warning: found banned word 'spam'
True
False
Valid PIN
⚠️ The in operator checks for a contiguous substring, not individual characters unless the substring is one
character long.

Page 9
Python Course Notes – Strings & Lists

1.6 F-Strings (Formatted String Literals)


F-strings, introduced in Python 3.6, are the modern and recommended way to embed variables and
expressions directly inside strings. They are faster, cleaner, and easier to read than older methods like
% formatting or .format().

Basic Syntax
Prefix the string with f (or F) and use {variable} or {expression} inside curly braces.
Example 1.6a – F-string basics
name = "Alice"
age = 25
city = "Bangalore"

# Old way ([Link])


msg1 = "Hello {}! You are {} years old.".format(name, age)

# F-string way (recommended)


msg2 = f"Hello {name}! You are {age} years old."
print(msg2)

# You can embed any expression


print(f"Next year you will be {age + 1}.")
print(f"Your name has {len(name)} characters.")
print(f"Name in uppercase: {[Link]()}")
print(f"You live in {city}.")
Hello Alice! You are 25 years old.
Next year you will be 26.
Your name has 5 characters.
Name in uppercase: ALICE
You live in Bangalore.

Number Formatting
F-strings support Python's format specification mini-language inside the curly braces using a colon:
{value:format_spec}

Example 1.6b – Formatting numbers


pi = 3.14159265358979
price = 1250.5
big = 1234567

# Decimal places
print(f"Pi = {pi:.2f}") # 2 decimal places
print(f"Pi = {pi:.5f}") # 5 decimal places

# Width and alignment


print(f"Price: {price:10.2f}") # width 10, 2 decimals
print(f"Pi: {pi:>10.3f}") # right-align in width 10
print(f"Pi: {pi:<10.3f}") # left-align in width 10

# Thousands separator
print(f"Population: {big:,}") # 1,234,567

# Percentage
score = 0.875

Page 10
Python Course Notes – Strings & Lists

print(f"Score: {score:.1%}") # 87.5%

# Binary, Octal, Hex


n = 255
print(f"Decimal: {n}") # 255
print(f"Binary: {n:b}") # 11111111
print(f"Octal: {n:o}") # 377
print(f"Hex: {n:x}") # ff
Pi = 3.14
Pi = 3.14159
Price: 1250.50
Pi: 3.142
Pi: 3.142
Population: 1,234,567
Score: 87.5%
Decimal: 255
Binary: 11111111
Octal: 377
Hex: ff

F-Strings with Expressions and Conditions


Example 1.6c – Expressions inside f-strings
# Mathematical expression
a, b = 12, 7
print(f"{a} + {b} = {a + b}")
print(f"{a} × {b} = {a * b}")
print(f"{a} ** 2 = {a ** 2}")

# Conditional expression (ternary)


score = 75
result = "Pass" if score >= 50 else "Fail"
print(result)

# Calling methods
items = ["apple", "banana", "cherry"]
print(", ".join(items))
print(f"Count: {len(items)}")

# Multi-line f-string
name = "Bob"
age = 30
status = "Adult" if age >= 18 else "Minor"
report = (
f"Name : {name}\n"
f"Age : {age}\n"
f"Status: {status}"
)
print(report)
12 + 7 = 19
12 × 7 = 84
12 ** 2 = 144
Score: 75 – Pass
Items: apple, banana, cherry
Count: 3
Name : Bob
Age : 30
Status: Adult

Page 11
Python Course Notes – Strings & Lists

💡 F-strings evaluate expressions at runtime. Keep them simple and readable — if the logic is complex,
compute it in a variable first, then use the variable in the f-string.

1.7 Useful String Methods


Python strings have a rich library of built-in methods. Because strings are immutable, all methods
return new strings rather than changing the original. Methods are called using dot notation:
[Link]().

Case Methods
Example 1.7a – Changing case
s = "Hello, World!"

print([Link]()) # "HELLO, WORLD!"


print([Link]()) # "hello, world!"
print([Link]()) # "Hello, World!" (each word capitalised)
print([Link]()) # "Hello, world!" (only first char)
print([Link]()) # "hELLO, wORLD!"

# Case-insensitive comparison
user_input = "YES"
if user_input.lower() == "yes":
print("User agreed")
"HELLO, WORLD!"
"hello, world!"
"Hello, World!"
"Hello, world!"
"hELLO, wORLD!"
User agreed

Stripping Methods
Example 1.7b – Removing whitespace and characters
# Whitespace stripping
s = " Hello, World! "
print(repr([Link]())) # "Hello, World!"
print(repr([Link]())) # "Hello, World! "
print(repr([Link]())) # " Hello, World!"

# Strip specific characters


url = "***important***"
print([Link]("*")) # "important"

text = "...Hello..."
print([Link](".")) # "Hello"

# Very useful for cleaning user input


user_name = " alice "
clean = user_name.strip()
print(f"User: [{clean}]")
"Hello, World!"
"Hello, World! "
" Hello, World!"
"important"

Page 12
Python Course Notes – Strings & Lists

"Hello"
"User: [alice]"

Searching Methods
Example 1.7c – Finding substrings
sentence = "the quick brown fox jumps over the lazy fox"

# find() – returns first index, or -1 if not found


print([Link]("fox")) # 16
print([Link]("cat")) # -1

# rfind() – searches from the RIGHT


print([Link]("fox")) # 40 (second "fox")

# index() – like find() but raises ValueError if not found


print([Link]("fox")) # 16
# [Link]("cat") ← ValueError

# count() – number of non-overlapping occurrences


print([Link]("fox")) # 2
print([Link]("the")) # 2

# startswith() and endswith()


filename = "report_2024.pdf"
print([Link]("report")) # True
print([Link](".pdf")) # True
print([Link](".docx")) # False
16
-1
40
16
2
2
True
True
False

Replacing and Splitting


Example 1.7d – replace() and split()
# replace(old, new) – replaces ALL occurrences
s = "I love cats. Cats are great. My cat is fluffy."
print([Link]("cat", "dog"))
print([Link]("cat", "dog", 2)) # replace only first 2

# split() – splits into a list


csv_line = "Alice,30,Engineer,Bangalore"
parts = csv_line.split(",")
print(parts)

sentence = "Hello World Python"


words = [Link]() # splits on whitespace by default
print(words)

# split with maxsplit


data = "a:b:c:d:e"

Page 13
Python Course Notes – Strings & Lists

print([Link](":", 2)) # ["a", "b", "c:d:e"]

# join() – opposite of split()


words = ["Python", "is", "awesome"]
print(" ".join(words)) # "Python is awesome"
print("-".join(words)) # "Python-is-awesome"
print("".join(words)) # "Pythonisawesome"
I love dogs. dogs are great. My dog is fluffy.
I love dogs. dogs are great. My cat is fluffy.
['Alice', '30', 'Engineer', 'Bangalore']
['Hello', 'World', 'Python']
['a', 'b', 'c:d:e']
Python is awesome
Python-is-awesome
Pythonisawesome

Checking Methods
Example 1.7e – is...() checking methods
# isdigit() – all characters are digits
print("123".isdigit()) # True
print("12.3".isdigit()) # False (dot is not a digit)

# isalpha() – all characters are letters


print("Hello".isalpha()) # True
print("Hello1".isalpha()) # False

# isalnum() – all letters or digits


print("Hello123".isalnum()) # True
print("Hello!".isalnum()) # False

# isspace() – only whitespace


print(" ".isspace()) # True

# isupper() / islower()
print("HELLO".isupper()) # True
print("hello".islower()) # True
print("Hello".isupper()) # False

# Practical: validate a PIN


pin = input("Enter PIN: ") # assume user enters "4821"
if [Link]() and len(pin) == 4:
print("Valid PIN")
else:
print("Invalid PIN")
True
False
True
False
True
False
True
True
True
False
Valid PIN

Page 14
Python Course Notes – Strings & Lists

Complete String Methods Reference Table


Method Description Example
upper() Convert to uppercase 'hello'.upper() → 'HELLO'
lower() Convert to lowercase 'HELLO'.lower() → 'hello'
title() Capitalise each word 'hi there'.title() → 'Hi
There'
capitalize() Capitalise first char only 'hello world'.capitalize()
→ 'Hello world'
swapcase() Swap upper/lower 'Hello'.swapcase() →
'hELLO'
strip() Remove leading/trailing whitespace ' hi '.strip() → 'hi'
lstrip() Remove leading whitespace ' hi'.lstrip() → 'hi'
rstrip() Remove trailing whitespace 'hi '.rstrip() → 'hi'
find(sub) First index of sub, -1 if missing 'abcabc'.find('b') → 1
rfind(sub) Last index of sub, -1 if missing 'abcabc'.rfind('b') → 4
index(sub) Like find(), raises ValueError if 'abc'.index('b') → 1
missing
count(sub) Non-overlapping occurrences 'banana'.count('a') → 3
replace(o,n) Replace old with new 'aab'.replace('a','x') →
'xxb'
split(sep) Split into list 'a,b'.split(',') →
['a','b']
join(iter) Join iterable into string ','.join(['a','b']) → 'a,b'
startswith(s) True if string starts with s 'Hello'.startswith('He') →
True
endswith(s) True if string ends with s 'Hello'.endswith('lo') →
True
isdigit() True if all chars are digits '123'.isdigit() → True
isalpha() True if all chars are letters 'abc'.isalpha() → True
isalnum() True if letters or digits only 'abc1'.isalnum() → True
isspace() True if all chars are whitespace ' '.isspace() → True
isupper() True if all chars are uppercase 'ABC'.isupper() → True
islower() True if all chars are lowercase 'abc'.islower() → True
center(w) Centre in field of width w 'hi'.center(6) → ' hi '
ljust(w) Left-justify in field of width w 'hi'.ljust(6) → 'hi '
rjust(w) Right-justify in field of width w 'hi'.rjust(6) → ' hi'
zfill(w) Pad with zeros on the left '42'.zfill(5) → '00042'
encode(enc) Encode string to bytes 'hi'.encode('utf-8') →
b'hi'
format(**kw) Format with named placeholders '{n}'.format(n='A') → 'A'

Page 15
Python Course Notes – Strings & Lists

PART 2 — LISTS
Lists are one of the most powerful and versatile data structures in Python. A list can hold an ordered
collection of items — numbers, strings, other lists, or any mix of types. Lists are mutable, meaning you
can change their contents after creation.

2.1 Introduction to Lists


A list is created by enclosing comma-separated values in square brackets []. Each item in the list is
called an element, and each element has a numeric index starting from 0.

Key Properties of Lists


• Ordered: Elements are stored in insertion order and that order is maintained.
• Mutable: You can add, remove, or change elements after creation.
• Heterogeneous: A single list can hold elements of different types.
• Dynamic: Lists grow and shrink automatically as needed.
• Nestable: Lists can contain other lists.

Example 2.1a – Creating various lists


# List of strings
fruits = ["apple", "banana", "cherry"]

# List of integers
numbers = [10, 20, 30, 40, 50]

# List of floats
temperatures = [36.5, 37.0, 38.2, 36.8]

# Mixed-type list
mixed = [1, "hello", 3.14, True, None]

# Empty list
empty = []

# Nested list (list of lists)


matrix = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]

print(fruits)
print(type(fruits)) # <class "list">
print(len(fruits)) # 3
['apple', 'banana', 'cherry']
<class 'list'>
3

2.2 Positive Indexes


Accessing elements of a list works exactly like accessing characters of a string. Each element has a
zero-based positive index from left to right.

Page 16
Python Course Notes – Strings & Lists

Example 2.2a – Positive index access


colors = ["red", "green", "blue", "yellow", "purple"]
# 0 1 2 3 4

print(colors[0]) # "red"
print(colors[1]) # "green"
print(colors[3]) # "yellow"
print(colors[4]) # "purple" (last element)

# Access elements of a nested list


matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(matrix[0]) # [1, 2, 3] (first row)
print(matrix[1][2]) # 6 (row 1, column 2)
print(matrix[2][0]) # 7 (row 2, column 0)
"red"
"green"
"yellow"
"purple"
[1, 2, 3]
6
7

2.3 Negative Indexes


Negative indexes let you access elements from the end of the list without knowing its exact length. -1
is always the last element.
Example 2.3a – Negative index access
fruits = ["apple", "banana", "cherry", "date", "elderberry"]
# -5 -4 -3 -2 -1

print(fruits[-1]) # "elderberry" (last)


print(fruits[-2]) # "date"
print(fruits[-5]) # "apple" (same as fruits[0])

# Practical: get the last element dynamically


scores = [88, 72, 95, 61, 79]
print(f"Last score: {scores[-1]}") # 79
print(f"Second last: {scores[-2]}") # 61

# Negative index in a loop


for i in range(1, 4):
print(f"From end [{-i}]: {scores[-i]}")
"elderberry"
"date"
"apple"
Last score: 79
Second last: 61
From end [-1]: 79
From end [-2]: 61
From end [-3]: 95

2.4 Slices
List slices work identically to string slices: list[start:end:step]. A slice returns a new list (it does
not modify the original).
Example 2.4a – List slicing

Page 17
Python Course Notes – Strings & Lists

nums = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]

print(nums[2:5]) # [20, 30, 40]


print(nums[:4]) # [0, 10, 20, 30]
print(nums[6:]) # [60, 70, 80, 90]
print(nums[::2]) # [0, 20, 40, 60, 80] (every 2nd)
print(nums[::-1]) # [90, 80, ..., 0] (reversed)
print(nums[1:8:3]) # [10, 40, 70] (step 3)

# Shallow copy of entire list


copy = nums[:]
copy[0] = 999
print(nums[0]) # 0 (original unchanged)
print(copy[0]) # 999
[20, 30, 40]
[0, 10, 20, 30]
[60, 70, 80, 90]
[0, 20, 40, 60, 80]
[90, 80, 70, 60, 50, 40, 30, 20, 10, 0]
[10, 40, 70]
0
999

Example 2.4b – Slice assignment (modifying part of a list)


letters = ["a", "b", "c", "d", "e"]

# Replace elements using slice


letters[1:3] = ["X", "Y"]
print(letters) # ["a", "X", "Y", "d", "e"]

# Delete elements using slice


letters[1:3] = []
print(letters) # ["a", "d", "e"]

# Insert elements (expand)


letters[1:1] = ["B", "C"]
print(letters) # ["a", "B", "C", "d", "e"]
["a", "X", "Y", "d", "e"]
["a", "d", "e"]
["a", "B", "C", "d", "e"]

2.5 The len() Function


The built-in len() function returns the number of elements in a list. This is commonly used with loops,
validation, and slicing.
Example 2.5a – Using len() with lists
fruits = ["apple", "banana", "cherry"]
print(len(fruits)) # 3

# Use len() to loop with index


for i in range(len(fruits)):
print(f"{i}: {fruits[i]}")

# Get last element safely


last = fruits[len(fruits) - 1]
print(last) # "cherry"

Page 18
Python Course Notes – Strings & Lists

# Empty list check


empty = []
if len(empty) == 0:
print("List is empty")

# Nested list
matrix = [[1,2,3],[4,5,6]]
print(len(matrix)) # 2 (number of rows)
print(len(matrix[0])) # 3 (number of columns)
3
0: apple
1: banana
2: cherry
"cherry"
List is empty
2
3

2.6 Updating Values in a List


Since lists are mutable, you can change any element by assigning to its index. You can also replace
multiple elements using slice assignment.
Example 2.6a – Modifying list elements
grades = [85, 72, 90, 65, 78]
print(grades) # original

# Update a single element


grades[1] = 80
print(grades) # [85, 80, 90, 65, 78]

# Update using negative index


grades[-1] = 82
print(grades) # [85, 80, 90, 65, 82]

# Update using slice (replace multiple at once)


grades[2:4] = [95, 70]
print(grades) # [85, 80, 95, 70, 82]

# Conditionally update
for i in range(len(grades)):
if grades[i] < 75:
grades[i] = 75 # no one gets below 75
print(grades)
[85, 72, 90, 65, 78]
[85, 80, 90, 65, 78]
[85, 80, 90, 65, 82]
[85, 80, 95, 70, 82]
[85, 80, 95, 75, 82]

2.7 Concatenation and Replication


Lists support the + operator for concatenation (joining) and the * operator for replication (repeating).
Example 2.7a – Concatenation and replication
# Concatenation with +
a = [1, 2, 3]

Page 19
Python Course Notes – Strings & Lists

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

# Augmented assignment +=
a += [4, 5]
print(a) # [1, 2, 3, 4, 5]

# Replication with *
zeros = [0] * 5
print(zeros) # [0, 0, 0, 0, 0]

pair = [1, 2] * 4
print(pair) # [1, 2, 1, 2, 1, 2, 1, 2]

# Practical: initialise a board


row = ["."] * 3
board = [row[:] for _ in range(3)] # 3x3 grid
board[1][1] = "X"
for r in board:
print(r)
[1, 2, 3, 4, 5, 6]
[1, 2, 3, 4, 5]
[0, 0, 0, 0, 0]
[1, 2, 1, 2, 1, 2, 1, 2]
['.', '.', '.']
['.', 'X', '.']
['.', '.', '.']
⚠️ Do NOT do board = [row] * 3 when row is a list — all three rows would reference the same object. Use a
list comprehension with row[:] to create independent copies.

2.8 The del Statement


The del statement removes elements from a list by index or slice. Unlike remove() which searches by
value, del works by position.
Example 2.8a – Using del
animals = ["cat", "dog", "bird", "fish", "hamster"]
print(animals) # original

# Delete by index
del animals[2] # removes "bird"
print(animals)

# Delete by negative index


del animals[-1] # removes "hamster"
print(animals)

# Delete a slice
del animals[1:3] # removes "dog" and "fish"
print(animals)

# Delete entire variable


del animals
# print(animals) ← NameError: name "animals" is not defined

# Practical: remove all elements from list


nums = [1, 2, 3, 4, 5]
del nums[:] # clears list (same as [Link]())

Page 20
Python Course Notes – Strings & Lists

print(nums) # []
['cat', 'dog', 'bird', 'fish', 'hamster']
['cat', 'dog', 'fish', 'hamster']
['cat', 'dog', 'fish']
['cat']
[]

2.9 Working with Lists


Lists have many practical patterns you will use constantly. This section covers common operations:
checking emptiness, sorting, copying, searching, and nesting.

Checking if a List is Empty


Example 2.9a – Empty list checks
items = []

# Method 1: compare length to 0


if len(items) == 0:
print("List is empty")

# Method 2: Pythonic way (empty list is falsy)


if not items:
print("No items found")

# Non-empty list is truthy


data = [1, 2, 3]
if data:
print(f"Found {len(data)} items")
List is empty
No items found
Found 3 items

Sorting Lists
Example 2.9b – Sorting
nums = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3]

# sort() modifies IN-PLACE, returns None


[Link]()
print(nums) # [1, 1, 2, 3, 3, 4, 5, 5, 6, 9]

# Descending order
[Link](reverse=True)
print(nums) # [9, 6, 5, 5, 4, 3, 3, 2, 1, 1]

# sorted() returns NEW list, original unchanged


original = [5, 2, 8, 1, 9]
new_sorted = sorted(original)
print(original) # [5, 2, 8, 1, 9] unchanged
print(new_sorted) # [1, 2, 5, 8, 9]

# Sort strings alphabetically


names = ["Charlie", "Alice", "Bob", "David"]
[Link]()

Page 21
Python Course Notes – Strings & Lists

print(names)

# Sort by length
words = ["banana", "fig", "apple", "kiwi"]
[Link](key=len)
print(words)
[1, 1, 2, 3, 3, 4, 5, 5, 6, 9]
[9, 6, 5, 5, 4, 3, 3, 2, 1, 1]
[5, 2, 8, 1, 9]
[1, 2, 5, 8, 9]
['Alice', 'Bob', 'Charlie', 'David']
['fig', 'kiwi', 'apple', 'banana']

Copying Lists
Example 2.9c – Copying lists correctly
original = [1, 2, 3, 4, 5]

# WRONG: assignment creates a reference, not a copy


alias = original
alias[0] = 999
print(original) # [999, 2, 3, 4, 5] ← original changed!

# CORRECT method 1: slice copy


original = [1, 2, 3, 4, 5]
copy1 = original[:]
copy1[0] = 999
print(original) # [1, 2, 3, 4, 5] ← unchanged

# CORRECT method 2: .copy() method


copy2 = [Link]()

# CORRECT method 3: list() constructor


copy3 = list(original)
print(copy2 == copy3) # True (same content)
[999, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
True
⚠️ Assignment (alias = original) does NOT copy a list — both variables point to the same object. Use slice
[:], .copy(), or list() to create an independent copy.

2.10 for Loops and Lists


The for loop is the standard and most Pythonic way to iterate over a list. Python provides several loop
patterns for different needs.

Basic for Loop


Example 2.10a – Simple iteration
fruits = ["apple", "banana", "cherry"]

# Iterate directly over elements


for fruit in fruits:
print(fruit)

Page 22
Python Course Notes – Strings & Lists

# Compute sum of a list


numbers = [10, 20, 30, 40, 50]
total = 0
for n in numbers:
total += n
print(f"Sum = {total}") # 150

# Find maximum manually


maximum = numbers[0]
for n in numbers:
if n > maximum:
maximum = n
print(f"Max = {maximum}") # 50
apple
banana
cherry
Sum = 150
Max = 50

Loop with Index – range(len())


Example 2.10b – Index-based loop
colors = ["red", "green", "blue"]

for i in range(len(colors)):
print(f"Index {i}: {colors[i]}")

# Useful when you need to modify elements


prices = [100, 200, 150, 300]
for i in range(len(prices)):
prices[i] = prices[i] * 0.9 # 10% discount
print(prices)
Index 0: red
Index 1: green
Index 2: blue
[90.0, 180.0, 135.0, 270.0]

enumerate() – Best of Both Worlds


Example 2.10c – Using enumerate()
students = ["Alice", "Bob", "Charlie", "Diana"]

# enumerate gives (index, value) pairs


for index, name in enumerate(students):
print(f"{index + 1}. {name}")

# Start index from 1 using start parameter


for rank, name in enumerate(students, start=1):
print(f"Rank {rank}: {name}")
1. Alice
2. Bob
3. Charlie
4. Diana
Rank 1: Alice
Rank 2: Bob

Page 23
Python Course Notes – Strings & Lists

Rank 3: Charlie
Rank 4: Diana

List Comprehensions
A list comprehension is a concise, Pythonic way to build a new list from an existing one in a single
line.
Example 2.10d – List comprehensions
# Syntax: [expression for item in iterable if condition]

# Squares of 1 to 10
squares = [x**2 for x in range(1, 11)]
print(squares)

# Even numbers only


evens = [x for x in range(1, 21) if x % 2 == 0]
print(evens)

# Convert all names to uppercase


names = ["alice", "bob", "charlie"]
upper_names = [[Link]() for name in names]
print(upper_names)

# Filter: only names longer than 3 chars


long_names = [name for name in names if len(name) > 3]
print(long_names)

# Extract numbers from a mixed list


mixed = [1, "a", 2, "b", 3, "c"]
nums_only = [x for x in mixed if isinstance(x, int)]
print(nums_only)
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
['ALICE', 'BOB', 'CHARLIE']
['alice', 'charlie']
[1, 2, 3]

zip() – Iterate Over Multiple Lists


Example 2.10e – Using zip() with lists
names = ["Alice", "Bob", "Charlie"]
scores = [95, 87, 92]
grades = ["A", "B", "A"]

for name, score, grade in zip(names, scores, grades):


print(f"{name}: {score} ({grade})")

# Create a dict from two lists


mapping = dict(zip(names, scores))
print(mapping)
Alice: 95 (A)
Bob: 87 (B)
Charlie: 92 (A)
{'Alice': 95, 'Bob': 87, 'Charlie': 92}

Page 24
Python Course Notes – Strings & Lists

💡 Prefer enumerate() over range(len(list)) when you need both index and value. Use zip() when iterating
over multiple lists in parallel.

2.11 in and not in Operators with Lists


The in and not in operators check whether a value is present anywhere in a list. They perform a
linear search through the list.
Example 2.11a – Membership testing
fruits = ["apple", "banana", "cherry", "date"]

print("apple" in fruits) # True


print("mango" in fruits) # False
print("mango" not in fruits) # True

# Guard against index errors


search = "cherry"
if search in fruits:
idx = [Link](search)
print(f"Found {search} at index {idx}")

# Check numbers
primes = [2, 3, 5, 7, 11, 13, 17, 19]
for n in range(1, 15):
status = "prime" if n in primes else "not prime"
print(f"{n} is {status}")
True
False
True
Found cherry at index 2
1 is not prime
2 is prime
3 is prime
...

Example 2.11b – in with nested lists and conditions


# Nested list – checks for complete sub-list
matrix = [[1, 2], [3, 4], [5, 6]]
print([3, 4] in matrix) # True
print([1, 3] in matrix) # False

# Practical: allowed users check


allowed_users = ["admin", "alice", "bob"]
current_user = "alice"

if current_user in allowed_users:
print(f"Access granted to {current_user}")
else:
print("Access denied")

# Remove duplicates using in


numbers = [1, 2, 3, 2, 4, 1, 5, 3]
unique = []
for n in numbers:
if n not in unique:
[Link](n)
print(unique)
True

Page 25
Python Course Notes – Strings & Lists

False
Access granted to alice
[1, 2, 3, 4, 5]

2.12 Multiple Assignment (Unpacking)


Python lets you assign multiple list items to multiple variables in one statement. This is called
unpacking or destructuring.
Example 2.12a – Basic unpacking
# Unpack all elements
point = [10, 20]
x, y = point
print(f"x={x}, y={y}") # x=10, y=20

rgb = [255, 128, 0]


red, green, blue = rgb
print(f"R={red} G={green} B={blue}")

# Swap two variables elegantly


a, b = 100, 200
print(f"Before: a={a}, b={b}")
a, b = b, a
print(f"After: a={a}, b={b}")
x=10, y=20
R=255 G=128 B=0
Before: a=100, b=200
After: a=200, b=100

Example 2.12b – Extended unpacking with *


numbers = [1, 2, 3, 4, 5, 6, 7]

# Capture first, last, and middle with *


first, *middle, last = numbers
print(f"First: {first}") # 1
print(f"Middle: {middle}") # [2, 3, 4, 5, 6]
print(f"Last: {last}") # 7

# First and rest


head, *tail = numbers
print(f"Head: {head}") # 1
print(f"Tail: {tail}") # [2, 3, 4, 5, 6, 7]

# All but last


*init, last = numbers
print(f"Init: {init}") # [1, 2, 3, 4, 5, 6]
print(f"Last: {last}") # 7

# Unpack in a for loop


pairs = [[1, "one"], [2, "two"], [3, "three"]]
for num, word in pairs:
print(f"{num} = {word}")
First: 1
Middle: [2, 3, 4, 5, 6]
Last: 7
Head: 1
Tail: [2, 3, 4, 5, 6, 7]
Init: [1, 2, 3, 4, 5, 6]

Page 26
Python Course Notes – Strings & Lists

Last: 7
1 = one
2 = two
3 = three
⚠️ The number of variables must match the number of elements unless you use * (star/splat) for variable-
length unpacking.

2.13 List Methods


Python lists have a comprehensive set of built-in methods. Most modify the list in-place and return
None. Understanding each method thoroughly is essential for efficient Python programming.

append() – Add One Element to End


Example 2.13a – append()
fruits = ["apple", "banana"]

[Link]("cherry")
print(fruits) # ["apple", "banana", "cherry"]

[Link]("date")
[Link]("elderberry")
print(fruits)

# Building a list dynamically


squares = []
for i in range(1, 6):
[Link](i ** 2)
print(squares) # [1, 4, 9, 16, 25]

# Appending a list adds it as ONE element


lst = [1, 2, 3]
[Link]([4, 5])
print(lst) # [1, 2, 3, [4, 5]]
["apple", "banana", "cherry"]
["apple", "banana", "cherry", "date", "elderberry"]
[1, 4, 9, 16, 25]
[1, 2, 3, [4, 5]]

insert() – Add Element at Specific Position


Example 2.13b – insert()
colors = ["red", "green", "blue"]

# insert(index, value)
[Link](0, "black") # insert at beginning
print(colors) # ["black", "red", "green", "blue"]

[Link](2, "yellow") # insert at position 2


print(colors) # ["black", "red", "yellow", "green", "blue"]

# Insert at end (same as append)


[Link](len(colors), "white")
print(colors)

Page 27
Python Course Notes – Strings & Lists

# Insert at index beyond range → inserts at end


[Link](100, "pink")
print(colors[-1]) # "pink"
["black", "red", "green", "blue"]
["black", "red", "yellow", "green", "blue"]

extend() – Add All Elements of Iterable


Example 2.13c – extend()
a = [1, 2, 3]
b = [4, 5, 6]

# extend adds EACH element of b to a


[Link](b)
print(a) # [1, 2, 3, 4, 5, 6]

# Compare: append adds b as ONE element


x = [1, 2, 3]
[Link](b)
print(x) # [1, 2, 3, [4, 5, 6]]

# Extend from any iterable


lst = [1, 2]
[Link]("abc") # strings are iterable!
print(lst) # [1, 2, "a", "b", "c"]

[Link](range(3, 6))
print(lst)
[1, 2, 3, 4, 5, 6]
[1, 2, 3, [4, 5, 6]]
[1, 2, "a", "b", "c"]
[1, 2, "a", "b", "c", 3, 4, 5]

remove() – Remove by Value


Example 2.13d – remove()
animals = ["cat", "dog", "bird", "dog", "fish"]

# Removes FIRST occurrence only


[Link]("dog")
print(animals) # ["cat", "bird", "dog", "fish"]

# Remove all occurrences using a loop


while "dog" in animals:
[Link]("dog")
print(animals) # ["cat", "bird", "fish"]

# Safe removal: check before removing


if "cat" in animals:
[Link]("cat")
print("Removed cat")

# ValueError if element not found


# [Link]("elephant") ← ValueError!
["cat", "bird", "dog", "fish"]
["cat", "bird", "fish"]

Page 28
Python Course Notes – Strings & Lists

Removed cat

pop() – Remove and Return by Index


Example 2.13e – pop()
stack = [10, 20, 30, 40, 50]

# pop() with no argument removes LAST element


last = [Link]()
print(f"Popped: {last}") # 50
print(stack) # [10, 20, 30, 40]

# pop(index) removes at given index


first = [Link](0)
print(f"Popped: {first}") # 10
print(stack) # [20, 30, 40]

# STACK behaviour (LIFO) using pop()


stack2 = []
[Link]("a") # push
[Link]("b") # push
[Link]("c") # push
print([Link]()) # "c" ← last in, first out
print([Link]()) # "b"
Popped: 50
[10, 20, 30, 40]
Popped: 10
[20, 30, 40]
"c"
"b"

sort() and reverse()


Example 2.13f – sort() and reverse()
nums = [5, 2, 9, 1, 7, 3]

[Link]() # ascending in-place


print(nums) # [1, 2, 3, 5, 7, 9]

[Link](reverse=True) # descending
print(nums) # [9, 7, 5, 3, 2, 1]

# Sort strings
words = ["banana", "Apple", "cherry", "date"]
[Link]() # case-sensitive (uppercase first)
print(words)

[Link](key=[Link]) # case-insensitive
print(words)

# reverse() just flips the order (no sorting)


letters = ["d", "b", "c", "a"]
[Link]()
print(letters)
[1, 2, 3, 5, 7, 9]
[9, 7, 5, 3, 2, 1]

Page 29
Python Course Notes – Strings & Lists

['Apple', 'banana', 'cherry', 'date']


['Apple', 'banana', 'cherry', 'date']
['a', 'c', 'b', 'd']

index(), count(), clear(), copy()


Example 2.13g – More list methods
nums = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]

# index() – find position of first occurrence


print([Link](5)) # 4
print([Link](5, 5)) # 8 (start searching from index 5)

# count() – count occurrences


print([Link](5)) # 3
print([Link](1)) # 2
print([Link](99)) # 0 (not found)

# clear() – remove all elements


temp = [1, 2, 3]
[Link]()
print(temp) # []

# copy() – shallow copy


original = [1, 2, 3]
duplicate = [Link]()
[Link](4)
print(original) # [1, 2, 3] unchanged
print(duplicate) # [1, 2, 3, 4]
4
8
3
2
0
[]
[1, 2, 3]
[1, 2, 3, 4]

Complete List Methods Reference Table


Method Description Example
append(x) Add x to the end [Link](4) → [1,2,3,4]
insert(i, x) Insert x at position i [Link](1,'a') →
[1,'a',2]
extend(iter) Add all items from iterable [Link]([4,5]) →
[1,2,3,4,5]
remove(x) Remove first occurrence of x [Link](2) → removes
first 2
pop(i=-1) Remove & return item at index i [Link]() → removes last
clear() Remove all items [Link]() → []
index(x[,s,e]) Index of first x (optional start/end) [5,3,5].index(5) → 0
count(x) Number of occurrences of x [1,2,1].count(1) → 2

Page 30
Python Course Notes – Strings & Lists

Method Description Example


sort(key,rev) Sort in-place [3,1,2].sort() → [1,2,3]
reverse() Reverse in-place [1,2,3].reverse() → [3,2,1]
copy() Return shallow copy new = [Link]()

PART 3 — QUICK REFERENCE


Use this section as a fast lookup guide when writing Python code.

String Quick Reference


• s = 'Hello' or s = "Hello" — create a string
• s[0] — first char; s[-1] — last char; s[i] — any char
• s[a:b] — substring from a to b-1; s[::-1] — reversed
• 'sub' in s — True if 'sub' appears in s
• f'Hello {name}' — embed variable in string
• [Link]() / [Link]() — case conversion
• [Link]() — remove whitespace; [Link](',') — split into list
• [Link]('a','b') — replace substrings; [Link]('x') — find position
• ','.join(lst) — join list into string

List Quick Reference


• lst = [1, 2, 3] — create a list
• lst[0] — first element; lst[-1] — last; lst[i] — any element
• lst[a:b] — sub-list; lst[::-1] — reversed copy
• len(lst) — number of elements
• lst[i] = x — update element; del lst[i] — delete element
• lst + lst2 — concatenate; lst * n — replicate
• x in lst — check membership
• a, b = lst — unpack; first, *rest = lst — extended unpack
• [Link](x) — add to end
• [Link](i, x) — insert at position
• [Link](lst2) — add multiple elements
• [Link](x) — remove by value
• [Link](i) — remove and return by index
• [Link]() — sort in-place; sorted(lst) — return sorted copy
• [Link]() — reverse in-place
• [Link](x) — find position of x
• [Link](x) — count occurrences

Page 31
Python Course Notes – Strings & Lists

• [Link]() — shallow copy


• [Link]() — remove all elements

Common Patterns
Read and clean user input
name = input("Enter name: ").strip().title()
print(f"Welcome, {name}!")

Count vowels in a string


def count_vowels(s):
return sum(1 for c in [Link]() if c in "aeiou")

print(count_vowels("Hello World")) # 3

Remove duplicates preserving order


def remove_duplicates(lst):
seen = []
return [x for x in lst if x not in seen and not [Link](x)]

print(remove_duplicates([1,2,3,2,1,4])) # [1,2,3,4]

Flatten a nested list


nested = [[1,2], [3,4], [5,6]]
flat = [x for sub in nested for x in sub]
print(flat) # [1, 2, 3, 4, 5, 6]

Group elements into chunks


def chunks(lst, n):
return [lst[i:i+n] for i in range(0, len(lst), n)]

print(chunks([1,2,3,4,5,6,7], 3)) # [[1,2,3],[4,5,6],[7]]

💡 Practice is the key to mastering Python. Try rewriting each example from memory, then experiment with
variations. The more you code, the more natural it becomes.

— End of Python Course Notes —

Page 32

You might also like