ICTPRG435 - Session 2: List and String Manipulation
Overview: This session covers commenting, Python lists and list manipulation (methods, slicing, mutability), Python strings (methods, slicing, formatting), converting between strings and lists, and a set of practical student activities.
This session focuses on:
Commenting code
Comments are ignored by the interpreter and exist to help humans understand code. Keep comments concise and relevant. Use comments to explain why something is done (not just what is obvious from the code).
However, while you are learning you might want to add comments to your code to help you remember how things work.
Forms of comments
- Single-line comments - start with
#.
# This is a single-line comment - Multiline strings / docstrings - triple quotes (
'''or""") are used for documentation strings. Use them to document modules, functions and classes; they are accessible viahelp()and.__doc__.
Single line comment example
# This is a full-line comment.
x = 10 # This is an inline comment, explaining the variable x.
print(x) # Output: 10
Docstring example
def add(x, y):
"""
Return the sum of x and y.
Parameters:
x (int): first addend
y (int): second addend
"""
return x + y
The benefits of adding comments to your code include:
- Planning and Reviewing: Used as a planning tool before writing new code. These comments should be deleted when the code has been applied, evaluated, and tested.
- Code Description: Comments can be used to clarify the purpose of a particular section of code.
- Algorithmic Description: When using algorithms, it might be helpful to describe how the algorithm works or how your code utilises it.
- Tagging: Tagging can be used to identify specific parts of code that contain known bugs or room for improvement. For instance, BUG, FIXME, and TODO.
Note: PEP 8 recommends a maximum line length of 79 characters for code. For block comments and docstrings, 72 characters is often recommended.
Python lists - introduction
A Python list is a built-in, ordered, and mutable collection data type that can store a sequence of items. These items are enclosed in square brackets [] and separated by commas. To each item within the list separated with a comma, assigned a number known as its index (or position) in the sequence, the first index is 0. To access an item in the list, the index value of the item is required as demonstrated in the examples below.
Basic examples
lst1 = [1, 0, 1] # list of integers
lst2 = ["ant", "apple", "pear"] # list of strings
lst3 = [True, False, False, True] # list of boolean values
lst4 = [[1,0,5,-5], ["a","apple","xyz"], [True, False]] # list of lists
print(lst1) # [1, 0, 1]
print(lst1[0]) # 1 ->access the first item (index 0) in lst1
print(lst2[-1]) # 'pear' -> access the last item in the lst2
print(lst2[2][0]) # 'p' -> first character of third item in the lst2
print(lst4[1][1][:3]) # 'app' -> the first three chars of the second element of the second sublist from lst4
List Manipulation (mutating operations)
List manipulation involves locating data, counting the number of occurrences, sorting, and reversing the data, as well as inserting items at the end, inserting items in specified places and removing items. Keep in mind that invoking these functions modifies the list because lists are mutable (changeable).
.append(x)- addxto the end..clear()- remove all items..copy()- shallow copy of the list..count(x)- number of occurrences ofx..index(x)- index of first occurrence ofx(raisesValueErrorif not found)..insert(i, x)- insertxbefore indexi..pop(i)- remove and return item at indexi(default last). RaisesIndexErrorif empty or index out of range..remove(x)- remove first occurrence ofxraisesValueErrorif not found)..reverse()- reverse the list in place..sort()- sort the list in place (usekey=andreverse=for control).
Examples of list manipulation
lst = [1, 3, 1, 15, 2]
lst.append(55) # adds an item to end of list -> [1, 3, 1, 15, 2, 55]
print(lst.count(1)) # counts how many items (1) appear in the list -> 2
print(lst.index(15)) # finds an index of item (15) in the list -> 3
lst1 = lst.copy() # creates a copy of the list
lst.remove(1) # removes the first occurrence (1) from the list -> [3, 1, 15, 2, 55]
x = lst.pop() # removes the last item from the list (55) and assigns it to variable x -> [3, 1, 15, 2], x = 15
x = lst.pop(0) # removes the first item from the list (3) and assigns it to variable x -> [1, 15, 2], x = 3
lst.reverse() # reverses items in the list -> [2, 15, 1]
lst.sort() # sorts in place -> [1, 2, 15]
lst.insert(1, 4) # adds an item (4) into specific position (1) -> [1, 4, 2, 15]
List Slicing
It is a common practice in python to manipulate a list using list slicing. List slicing allows you to access a range of items from a list.
Syntax: list[start:stop:step]. Where:
start– The index where the slice begins (inclusive). If omitted, slicing starts from the beginning of the list.stop– The index where the slice ends (exclusive). If omitted, slicing continues to the end of the list.step– The interval between elements (default is 1).
Slicing returns a new list (it does not change the original).
Examples
lst = [1, 0, 1, 15, 2]
lst[:2] # first two items -> [1, 0]
lst[1:3] # from index 1 up to index 3 (but index 3 not included) -> [0, 1]
lst[2:] # from index 2 to end -> [1, 15, 2]
lst[-2:] # last two items -> [15, 2]
lst[::-1] # reversed list -> [2, 15, 1, 0, 1]
lst[::2] # every second item -> [1, 1, 2]
# substitute a slice
lst[1:3] = ["a", "b"] # replace positions 1 and 2 -> [1, 'a', 'b', 15, 2]
# delete slice
del lst[1:3] # removes items in positions 1 and 2 -> [1, 15, 2]
Note: Slicing returns a new list object; assignment into a slice can change the original list contents.
Python strings
Strings are sequences of characters and are immutable. Use single, double or triple quotes. Triple-quoted strings are commonly used for multiline text and docstrings.
Examples
str1 = 'Hello World!'
str2 = "Good morning class."
str3 = '''single-quoted triple'''
str4 = """double-quoted triple"""
str5 = '''This is
a multi-line
string'''
Important: Because strings are immutable, operations that appear to modify a string actually create a new string object. The id() value may change; however, the exact memory behaviour is implementation dependent and should not be relied upon.
Immutable vs mutable
# Strings are immutable
s = "Good Morning"
print(id(s))
s = s + "!!!" # creates a new string object
print(id(s)) # id will be different
# Lists are mutable
lst = [1, 0, 1, 15, 2]
print(id(lst))
lst.pop() # modifies same list object
print(id(lst)) # id remains the same
Common string methods
.lower()- lower-case copy..upper()- upper-case copy..replace(old, new[, count])- return new string with replacements..index(sub)- index of first occurrence (raisesValueErrorif not found).find(sub)- returns index of the first occurrence. Returns-1when not found..split(sep)- split into a list of substrings.'.'.join(iterable)- join elements of an iterable into a string using the separator.
Examples
str1 = 'Hello World'
print(str1.lower()) # converts to lowercase -> 'hello world'
print(str1.upper()) # converts to uppercase -> 'HELLO WORLD'
print(str1.replace('Hello', 'Hi')) # Replace "Hello" with "Hi" -> 'Hi World'
print(str1.index("W")) # returns index of the first occurrence -> 6
print(str1.index("Z")) # if not found, raises ValueError
print(str1.find("W")) # returns index of the first occurrence -> 6
print(str1.find("Z")) # returns -1 if not found -> -1
print(str1.split(' ')) # returns a list of substrings -> ["Hello", "World"]
print("-".join(["Hello", "World"])) # joins list items in a string, using separator -> "Hello-World"
Common string functions
chr(number)- converts a decimal value into an Ascii characterord(character)- converts an Ascii character into a decimal valuelen(string)- length of the string.str(number)- convert a value to its string representation.
Examples
print(chr(77)) # converts a decimal value into an Ascii character -> 'M'
print(ord('M')) # converts an Ascii character into a decimal value -> 77
print(len('Hello')) # returns length of the string -> 5
print(str(55)) # convert a value to its string representation -> "55"
Formatted string literals (f-strings)
Use f-strings for readable and powerful inline formatting (Python 3.6+).
Here are a few examples of f-strings
name = "Hello"
word = "World"
s = f"{name} {word}" # "Hello World"
num = 1000000000
print(f"{num:,}") # "1,000,000,000" (thousands separator)
n = 15
print(f"{n:b}") # Binary representation of integer -> '1111'
print(f"{n:x}") # Hexadecimal (lowercase) representation of integer -> 'f'
print(f"{n:o}") # Octal representation of integer -> '17'
print(f"{n:.1f}") # Fixed-point float format with 1 decimal place -> '15.0'
print(f"{0.5:.0%}") # Percentage format: multiplies by 100 and appends '%' -> '50%'
print(f"{n:02x}") # Format integer as lowercase hexadecimal, minimum width 2, zero-padded -> '0f'
# Note: width is a minimum — larger values will use more digits (e.g. 256 -> '100').
String slicing and indexing
Slicing syntax mirrors lists: s[start:stop:step]. Indexing uses zero-based numeric positions
or negative indices for the end.
Syntax: string[start:stop:step]. Where:
start– The index where the slice begins (inclusive). If omitted, slicing starts from the beginning of the string.stop– The index where the slice ends (exclusive). If omitted, slicing continues to the end of the string.step– The interval between elements (default is 1).
Slicing returns a new string (it does not change the original).
s = "It is a great day."
print(s[:5]) # first two characters -> 'It is'
print(s[3:]) # from index 3 up to the end -> 'is a great day.'
print(s[-2:]) # last two characters -> 'y.'
print(s[::-1]) # reversed string -> '.yad taerg a si tI'
print(s[::2]) # every second character -> 'I sagetdy'
print(s[-1]) # last character -> '.'
String operators
Python also provides string operators to facilitate string manipulation.
+concatenation:'Hello ' + 'World!' -> 'Hello World'*repetition:'Hi' * 3 -> 'HiHiHi'\escape sequences:"I enjoy \"Python\""
Converting between strings and lists
Strings to lists: .split()
The split(sep, maxsplit) method is used to split a string into a list. This method can accept 2 optional parameters:
separator– Specifies the separator. By default, the separator is a whitespace.maxsplit– Specifies the maximum number of splits. By default, no limits.
Examples
s = "Hello World, Hello!"
s.split() # ['Hello', 'World,', 'Hello!']
"one two three four five".split(" ", 2) # ['one', 'two', 'three four five']
"We, are, python, programmers".split(", ") # ['We', 'are', 'python', 'programmers']
Lists to strings: .join()
The .join() method is used to join all items from an iterable (such as a list) into a string.
Examples
words = ["Python", "programming", "is", "enjoyable"]
" ".join(words) # 'Python programming is enjoyable'
items = ["Three", "Two", "One", "Blast Off"]
", ".join(items) # 'Three, Two, One, Blast Off'
Useful built-ins and tips
- Prefer
.find()method when you want a safe "not found" result instead of an exception. - Be careful inserting or removing items while iterating the same list - iterate over a copy (
for x in lst[:]) or build a new list. - Case sensitivity: many string operations are case-sensitive; use
.lower()or.casefold()for case-insensitive comparisons.
Student activities
Note: the incomplete .py files for these activities are on the resources page (Session 2 files). Each activity below includes a clear specification and an example output.
Activity 1 - first/last with asterisk
Spec: Complete func(text) to return the first character, then
*, then the last character. If the word length is 1 or 2, return word without *.
# Examples
func("find") -> "f*d"
func("bottle") -> "b*e"
func("I") -> "I"
func("be") -> "be"
Activity 2 - last three reversed, repeated
Spec: Return last three characters reversed, repeated three times. If the word has fewer than three characters, operate on the whole word.
# Examples
func("hello") -> "ollolloll"
func("cotton") -> "tontonton"
func("Hi") -> "iHiHiH"
Activity 3 - swap first letters and format
Spec: Accept two words, swap their first characters, and return a sentence using an f-string. Keep the rest of each word unchanged.
# Example
func("runny", "face") -> "That was a funny race."
Activity 4 - replace vowels
Spec: Replace every vowel (a, e, i, o, u - both cases) with an asterisk (*) and return the new string.
func("Monty Python Flying Circus TV Show is Where the language Python got its name.")
# -> "M*nty Pyth*n Fly*ng C*rc*s TV Sh*w *s Wh*r* th* l*ng**g* Pyth*n g*t *ts n*m*."
Activity 5 - sorted words
Spec: Return a list of words from a sentence sorted alphabetically. Preserve original capitalization of words but treat words as separate tokens.
func("The Cat Sat On The Mat") -> ['Cat', 'Mat', 'On', 'Sat', 'The', 'The']
Activity 6 - set() research
Spec: Add comments to the provided script explaining what set() does, why order is unpredictable
Activity 7 - merge, unique, sorted
Spec: Accept two strings, split into words, combine both sets of words without duplicates, sort alphabetically and return the resulting list.
func("The Cat Sat On The Mat", "The Cat Ate The Rat")
# -> ['Ate', 'Cat', 'Mat', 'On', 'Rat', 'Sat', 'The']