Last updated: 2026-05-21

Lists and String Methods

Lists and strings are two of the most frequently used data types in Python. Both are sequences — ordered collections of items that support indexing, slicing, and iteration. Strings are sequences of characters; lists are sequences of any values. Understanding both in depth, along with their built-in methods, is essential for writing practical Python code.


Lists

A list is an ordered, mutable collection of items. Items can be of any type — including mixed types — and the list can grow or shrink after creation.

fruits = ["apple", "banana", "cherry"]
mixed = [1, "hello", True, 3.14, None]
empty = []
nested = [[1, 2], [3, 4], [5, 6]]

Accessing Items — Indexing

Lists are zero-indexed. Negative indices count from the end:

fruits = ["apple", "banana", "cherry"]

fruits[0]     # "apple"
fruits[1]     # "banana"
fruits[-1]    # "cherry" — last item
fruits[-2]    # "banana" — second to last

Accessing a Range — Slicing

fruits = ["apple", "banana", "cherry", "date", "elderberry"]

fruits[1:4]    # ["banana", "cherry", "date"] — index 1 up to (not including) 4
fruits[:3]     # ["apple", "banana", "cherry"] — from start to index 3
fruits[2:]     # ["cherry", "date", "elderberry"] — from index 2 to end
fruits[::2]    # ["apple", "cherry", "elderberry"] — every second item
fruits[::-1]   # ["elderberry", "date", "cherry", "banana", "apple"] — reversed

Slicing never raises an error for out-of-range indices — it simply returns what is available.

Modifying Items

Lists are mutable — you can change items after creation:

fruits = ["apple", "banana", "cherry"]
fruits[1] = "blueberry"
print(fruits)    # ["apple", "blueberry", "cherry"]

List Methods

Adding Items

fruits = ["apple", "banana"]

fruits.append("cherry")          # Add to the end
# ["apple", "banana", "cherry"]

fruits.insert(1, "blueberry")    # Insert at index 1
# ["apple", "blueberry", "banana", "cherry"]

fruits.extend(["date", "elderberry"])   # Add all items from another list
# ["apple", "blueberry", "banana", "cherry", "date", "elderberry"]

Removing Items

fruits = ["apple", "banana", "cherry", "banana"]

fruits.remove("banana")    # Removes the first occurrence
# ["apple", "cherry", "banana"]

fruits.pop()               # Removes and returns the last item
# Returns "banana", list becomes ["apple", "cherry"]

fruits.pop(0)              # Removes and returns item at index 0
# Returns "apple", list becomes ["cherry"]

fruits.clear()             # Removes all items
# []

Searching

fruits = ["apple", "banana", "cherry", "banana"]

fruits.index("banana")     # 1 — index of first occurrence
fruits.count("banana")     # 2 — how many times it appears
"cherry" in fruits         # True — membership check

Sorting and Reversing

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

numbers.sort()              # Sorts in place — ascending
# [1, 1, 2, 3, 4, 5, 6, 9]

numbers.sort(reverse=True)  # Sorts in place — descending
# [9, 6, 5, 4, 3, 2, 1, 1]

numbers.reverse()           # Reverses in place

sort() modifies the list in place and returns None. sorted() returns a new sorted list and leaves the original unchanged:

original = [3, 1, 4, 1, 5]
new = sorted(original)      # New sorted list
print(original)             # [3, 1, 4, 1, 5] — unchanged
print(new)                  # [1, 1, 3, 4, 5]

Copying a List

original = [1, 2, 3]

copy = original.copy()     # Shallow copy
copy2 = original[:]        # Also a shallow copy using slicing
copy3 = list(original)     # Also a shallow copy

Important: Assigning a list to a new variable does not copy it — both variables point to the same list:

a = [1, 2, 3]
b = a              # b is NOT a copy — it is the same list
b.append(4)
print(a)           # [1, 2, 3, 4] — a was also modified

Other Useful Methods

fruits = ["apple", "banana", "cherry"]

len(fruits)          # 3 — number of items
min([3, 1, 4])       # 1 — smallest value
max([3, 1, 4])       # 4 — largest value
sum([1, 2, 3, 4])    # 10 — sum of all items
list(reversed(fruits))  # ["cherry", "banana", "apple"]

List Comprehensions

List comprehensions are Python's concise, readable way to create a new list by transforming or filtering an existing iterable. They are one of Python's most distinctly Pythonic features.

# Basic syntax: [expression for item in iterable]
squares = [x ** 2 for x in range(1, 6)]
print(squares)    # [1, 4, 9, 16, 25]

With a condition (filter):

# [expression for item in iterable if condition]
evens = [x for x in range(10) if x % 2 == 0]
print(evens)    # [0, 2, 4, 6, 8]

Transforming a list of strings:

fruits = ["apple", "banana", "cherry"]
upper = [fruit.upper() for fruit in fruits]
print(upper)    # ["APPLE", "BANANA", "CHERRY"]

The equivalent using a for loop is more verbose:

upper = []
for fruit in fruits:
    upper.append(fruit.upper())

List comprehensions are preferred for simple transformations. For complex logic, a regular loop is clearer.


Strings

Strings are immutable sequences of characters. Every string method returns a new string — the original is never modified.

name = "Wariz"
name[0] = "w"    # ❌ TypeError — strings are immutable

Indexing and Slicing

Strings support the same indexing and slicing syntax as lists:

name = "Wariz"

name[0]       # "W"
name[-1]      # "z"
name[1:4]     # "ari"
name[::-1]    # "ziraW" — reversed

String Methods

Case Methods

text = "hello world"

text.upper()        # "HELLO WORLD"
text.lower()        # "hello world"
text.title()        # "Hello World" — capitalises first letter of each word
text.capitalize()   # "Hello world" — capitalises only the first letter
text.swapcase()     # "HELLO WORLD" → "hello world" and vice versa

Whitespace Methods

text = "  hello world  "

text.strip()        # "hello world" — removes leading and trailing whitespace
text.lstrip()       # "hello world  " — removes leading only
text.rstrip()       # "  hello world" — removes trailing only

Search and Check Methods

text = "Hello, World!"

text.find("World")          # 7 — index of first occurrence (-1 if not found)
text.index("World")         # 7 — same, but raises ValueError if not found
text.rfind("l")             # 10 — last occurrence
text.count("l")             # 3 — number of occurrences
text.startswith("Hello")    # True
text.endswith("!")          # True
"hello" in text             # False — case-sensitive
"Hello" in text             # True

Replace and Split

text = "Hello, World!"

text.replace("World", "Python")    # "Hello, Python!"
text.replace("l", "r", 2)         # Replace first 2 occurrences only

sentence = "apple,banana,cherry"
sentence.split(",")                # ["apple", "banana", "cherry"]
"hello world".split()              # ["hello", "world"] — splits on whitespace
"hello world".split(" ", 1)       # ["hello", "world"] — max 1 split

Join

join() is the reverse of split() — it combines a list of strings into one:

words = ["apple", "banana", "cherry"]
", ".join(words)    # "apple, banana, cherry"
" | ".join(words)   # "apple | banana | cherry"
"".join(["a", "b", "c"])   # "abc"

Check Methods

"hello".isalpha()      # True — all alphabetic characters
"hello123".isalnum()   # True — all alphanumeric
"12345".isdigit()      # True — all digits
"  ".isspace()         # True — all whitespace
"Hello World".istitle() # True — title case
"HELLO".isupper()      # True — all uppercase
"hello".islower()      # True — all lowercase

Formatting Methods

"hello".center(11)           # "   hello   " — centred in 11 characters
"hello".ljust(10)            # "hello     " — left-aligned, padded
"hello".rjust(10)            # "     hello" — right-aligned, padded
"hello".center(11, "-")      # "---hello---" — with fill character
"42".zfill(5)                # "00042" — zero-padded

f-strings vs. .format()

f-strings are the modern, preferred approach:

name = "Wariz"
age = 20

# f-string (Python 3.6+) — preferred
f"Hello, {name}. You are {age} years old."

# .format() — older approach, still valid
"Hello, {}. You are {} years old.".format(name, age)
"Hello, {name}. You are {age} years old.".format(name=name, age=age)

Useful Built-in Functions for Sequences

These work on both lists and strings:

fruits = ["apple", "banana", "cherry"]

len(fruits)           # 3 — length
min(fruits)           # "apple" — lexicographically smallest
max(fruits)           # "cherry" — lexicographically largest
sorted(fruits)        # New sorted list
list(reversed(fruits)) # ["cherry", "banana", "apple"]
enumerate(fruits)     # Pairs of (index, value)

Summary

List Methods

MethodWhat It Does
append(item)Adds item to the end
insert(i, item)Inserts item at index i
extend(iterable)Adds all items from iterable
remove(item)Removes first occurrence of item
pop(i)Removes and returns item at index i (default: last)
clear()Removes all items
index(item)Returns index of first occurrence
count(item)Counts occurrences
sort()Sorts in place
reverse()Reverses in place
copy()Returns a shallow copy

String Methods

MethodWhat It Does
upper() / lower()Changes case
title() / capitalize()Capitalises words or first letter
strip() / lstrip() / rstrip()Removes whitespace
find(s) / index(s)Finds substring position
count(s)Counts occurrences of substring
startswith(s) / endswith(s)Checks start or end
replace(old, new)Replaces substring
split(sep)Splits into a list
join(iterable)Joins list into a string
isalpha() / isdigit() / isalnum()Checks character types
zfill(n)Zero-pads to length n