Study guide
4.2 String Indexing, Slicing, and Comparison
OpenEDG PCAP — Certified Associate in Python Programming Exam
Track your progress as you read
Finished sections get a check mark.
1 Chapter 1: The PCAP-31-03 Exam Blueprint and Test-Day Logistics
1.1 The PCAP-31-03 Blueprint, Scoring, and Exam-Day Logistics
2 Chapter 2: Modules, Packages, and the Standard Library
2.1 Module Imports and Namespace Mechanics 2.2 Module Construction and Execution 2.3 Package Hierarchy and Navigation 2.4 Standard Library Modules and Pip
3 Chapter 3: Exceptions and Error Handling
3.1 Exception Control Flow and Syntax 3.2 The Built-in Exception Hierarchy 3.3 Raising Exceptions and Assertions 3.4 Custom Exceptions and Exception Chaining
4 Chapter 4: Strings, Encodings, and Text Processing
4.1 Character Encodings and String Immutability 4.2 String Indexing, Slicing, and Comparison 4.3 String Inspection and Classification Methods 4.4 String Transformation and Formatting Methods 4.5 Iterating, Sorting, and Comparing Strings Against Other Types
5 Chapter 5: Object-Oriented Programming Fundamentals
5.1 Classes, Instances, and Attributes 5.2 Encapsulation, Privacy, and Name Mangling 5.3 Dunder Methods and Object Lifecycle 5.4 Discovering Class Structure: __name__, __module__, __bases__, and Identity
6 Chapter 6: Advanced OOP, Inheritance, and Metaprogramming
6.1 Single Inheritance, Method Overriding, and Polymorphism 6.2 Multiple Inheritance and Method Resolution Order (MRO) 6.3 Class Methods, Static Methods, and Properties
7 Chapter 7: Functional Python, Comprehensions, and Closures
7.1 List, Dictionary, and Set Comprehensions 7.2 Lambda Expressions and Higher-Order Functions 7.3 Variable Scopes, the LEGB Rule, and Closures
8 Chapter 8: Iterators, Generators, and File I/O
8.1 Iterators and the Iteration Protocol 8.2 Generator Functions and Generator Expressions 8.3 File Input/Output and Context Managers 8.4 Predefined Streams, Handles vs. Streams, and errno Diagnostics
4.2 String Indexing, Slicing, and Comparison
Key Takeaways Explain This Topic AI
Positive indexing begins at 0 and increments to len(s) - 1 , while negative indexing begins at -1 (the last character) and decrements to -len(s) ; indexing outside this range raises IndexError .
Slicing uses the syntax s[start:stop:step] and is boundary-tolerant, never raising an IndexError even when indices lie completely outside the string's length.
Negative slice steps reverse traversal direction, causing start to default to len(s) - 1 and stop to default to the position before index 0, making s[::-1] the standard reversal idiom.
Sequence operators allow string concatenation ( + ), integer repetition ( * ), and substring membership verification ( in and not in ).
String comparison operators compare strings lexicographically code point by code point, which makes all ASCII uppercase letters evaluate as strictly less than lowercase letters ( 'Z' < 'a' ).
Last updated: August 2026
String Indexing, Slicing, and Comparison
Strings in Python are ordered sequences of individual characters. Because they are sequences, they support all standard Python sequence operations, including direct indexing, advanced slicing, repetition, concatenation, and relational comparisons.
1. String Indexing Mechanics
Every character in a string occupies a fixed positional index. Python supports dual indexing:
Positive Indexing (Forward): Starts at 0 for the first character and advances to len(s) - 1 for the final character.
Negative Indexing (Backward): Starts at -1 for the rightmost character and decrements to -len(s) for the leftmost character. String: P Y T H O N
- Positive Index: 0 1 2 3 4 5
- Negative Index: -6 -5 -4 -3 -2 -1 language = "PYTHON"
- # Positive indexing
- print(language[0]) # 'P'
- print(language[5]) # 'N'
- # Negative indexing
- print(language[-1]) # 'N' (last character)
- print(language[-6]) # 'P' (first character)
- The IndexError Trap
Attempting to access an index outside the valid range [-len(s), len(s) - 1] immediately triggers an IndexError : s = "PYTHON" # len(s) is 6
- # Out-of-bounds access raises IndexError
- # s[6] -> IndexError: string index out of range
- # s[-7] -> IndexError: string index out of range
Type Requirement: String indices must be integers. Passing floats (e.g., s[1.0] ) or strings raises a TypeError: string indices must be integers .
2. Slicing Syntax and Parameter Defaults
Slicing creates a new substring from an existing string using the slice bracket syntax: string [ start : stop : step ] \text{string}[\text{start} : \text{stop} : \text{step}] string [ start : stop : step ]
start : The index where extraction begins (inclusive).
stop : The index where extraction terminates (exclusive; the character at stop is never included).
step : The stride or step interval between extracted characters (defaults to +1 ).
Default Values for Positive Step ( step > 0 )
When step is positive (or omitted):
start defaults to 0 (the beginning of the string).
stop defaults to len(s) (the end of the string).
step defaults to 1 . s = "PROGRAMMING"
- print(s[0:4]) # 'PROG' (indices 0, 1, 2, 3)
- print(s[:7]) # 'PROGRAM' (start defaults to 0)
- print(s[7:]) # 'MING' (stop defaults to len(s))
- print(s[:]) # 'PROGRAMMING' (full shallow copy)
- print(s[::2]) # 'PGAMNG' (every 2nd character: indices 0, 2, 4, 6, 8, 10)
- 3. Boundary Tolerance in Slicing
A critical distinction on the PCAP exam is the difference in error handling between direct indexing and slicing:
Direct Indexing ( s[i] ): Strict boundary checking. Out-of-range indices raise IndexError .
Slicing ( s[start:stop] ): Completely boundary-tolerant. Python automatically clamps out-of-range boundaries to valid sequence limits without raising any errors. s = "PYTHON" # len(s) == 6
- # Slices extending far beyond string boundaries
- print(s[2:100]) # 'THON' (clamps stop to 6)
- print(s[10:20]) # '' (empty string, start is past the end)
- print(s[-100:2]) # 'PY' (clamps start to 0)
- print(s[5:2]) # '' (empty string, stop <= start with positive step)
- 4. Negative Steps and String Reversal
When step < 0 , the traversal direction is reversed (moving from right to left). This inverts the default slice boundaries:
start defaults to len(s) - 1 (the last character).
- stop defaults to one position before index 0 (so index 0 is included). Reversal Idiom: s[::-1]
- Traverses from the last character back to the first character. s = "PYTHON"
- # Standard reversal idiom
- print(s[::-1]) # 'NOHTYP'
- # Slice with explicit negative indices and step
- # Starts at index 4 ('O'), stops BEFORE index 1 ('Y')
- print(s[4:1:-1]) # 'OHT' (indices 4, 3, 2)
- # Direction conflict returning empty string
- # Moving left-to-right with start < stop but negative step
- print(s[1:4:-1]) # ''
- Step Arithmetic Rule Table
- Expression Start Index Stop Index Step Output on "PYTHON"
- s[1:5:2] 1 ( 'Y' ) 5 ( 'N' ) +2 'YH' (indices 1, 3)
- s[5:0:-2] 5 ( 'N' ) 0 ( 'P' ) -2 'NHY' (indices 5, 3, 1)
- s[-2:-5:-1] -2 ( 'O' ) -5 ( 'Y' ) -1 'OHT' (indices -2, -3, -4)
- s[-4:] -4 ( 'T' ) 6 ( len ) +1 'THON' (indices -4, -3, -2, -1)
- 5. Sequence Operators: +, *, in, and not in
Strings support sequence concatenation, repetition, and membership testing:
Concatenation ( + )
Combines two strings into a newly allocated string object. Both operands must be str : greeting = "Hello" + " " + "World"
print(greeting) # "Hello World"
# Mixed type error:
- # "Score: " + 100 # TypeError: can only concatenate str (not "int") to str
- Repetition ( * )
Replicates a string by an integer multiplier. The multiplier can appear on either side ( s * n or n * s ): print("-" * 5) # "-----"
- print(3 * "Abc") # "AbcAbcAbc"
- print("Python" * 0) # "" (multiplier <= 0 yields an empty string)
- print("Python" * -3)# ""
- Membership Testing ( in and not in )
Tests whether a target substring exists as a contiguous slice within the string: text = "Object Oriented Programming"
- print("Oriented" in text) # True
- print("oriented" in text) # False (case-sensitive)
- print("OOP" in text) # False (must be contiguous)
- print("xyz" not in text) # True
# The empty string rule:
- # The empty string is considered a substring of EVERY string (including "")
- print("" in text) # True
- print("" in "") # True
- 6. Lexicographical Comparison Rules
Python compares strings using relational operators ( < , <= , == , != , >= , > ):
Comparisons are performed lexicographically (character-by-character from left to right).
Each character's ordinal position is determined strictly by its Unicode code point ( ord() ).
The comparison halts at the very first mismatched character.
The ASCII / Code Point Hierarchy
Because ASCII values dictate order: Digits (’0’-’9’: 48-57) < Uppercase (’A’-’Z’: 65-90) < Lowercase (’a’-’z’: 97-122) \text{Digits ('0'-'9': 48-57)} < \text{Uppercase ('A'-'Z': 65-90)} < \text{Lowercase ('a'-'z': 97-122)} Digits (’0’-’9’: 48-57) < Uppercase (’A’-’Z’: 65-90) < Lowercase (’a’-’z’: 97-122) # 1. Case sensitivity: All uppercase letters precede all lowercase letters
- print('Apple' < 'apple') # True ('A' is 65, 'a' is 97)
- print('Zebra' < 'ant') # True ('Z' is 90, 'a' is 97)
- # 2. Digit strings vs Alphabet strings
- print('9' < 'A') # True ('9' is 57, 'A' is 65)
- # 3. Numeric string comparison pitfall
- print('100' < '20') # True ('1' is 49, '2' is 50; '1' < '2')
- print(100 < 20) # False (integer comparison compares numeric magnitude)
- # 4. Prefix comparison rule (shorter prefix is smaller)
- print('app' < 'apple') # True (all matching, 'app' is shorter)
- 7. Built-in Functions: min() and max() on Strings
When applied to a string, min() and max() return the individual characters with the lowest and highest Unicode code points, respectively: word = "Python"
- print(min(word)) # 'P' (code point 80; 'h'=104, 'n'=110, 'o'=111, 't'=116, 'y'=121)
- print(max(word)) # 'y' (code point 121)
- phrase = "Hello World"
- print(min(phrase)) # ' ' (space character has code point 32, which is lowest)
- # Empty sequence error
- # min("") # ValueError: min() arg is an empty sequence