2.6. Lecture 5: Python 3¶
Before this class you should:
Read Think Python:
Chapter 8: Strings;
Chapter 10: Lists;
Chapter 11: Dictionaries; and
Chapter 12: Tuples
Before next class you should:
Read Think Python:
Chapter 15: Classes and objects;
Chapter 16: Classes and functions;
Chapter 17: Classes and methods; and
Chapter 18: Inheritance
Note taker: Evan Rutten
2.6.1. Strings¶
2.6.1.1. A String is a Sequence¶
A string is a sequence of characters that can be accessed one at a time with the bracket operator:
fruit = 'banana'
letter = fruit[1] # Gets 'a'
The index indicates which character in the sequence you want:
Indexing starts at 0 (first character)
The index must be an integer
You can use expressions containing variables and operators as indices
Negative indices count backward from the end of the string
2.6.1.2. Length¶
The len()
function returns the number of characters in a string:
fruit = 'banana'
length = len(fruit) # Returns 6
2.6.1.3. String Traversal¶
You can process a string one character at a time using either a while
loop or a for
loop.
Using while
:
index = 0
while index < len(fruit):
letter = fruit[index]
print(letter)
index = index + 1
Using for
(preferred):
for letter in fruit:
print(letter)
2.6.1.4. String Slices¶
A segment of a string is called a slice. Selecting a slice is similar to selecting a character:
s = 'Monty Python'
first = s[0:5] # Gets 'Monty'
second = s[6:12] # Gets 'Python'
Slice features:
[n:m]
returns part of string from “n-eth” to “m-eth” characterIncludes first position, excludes last position
Omitting first index starts from beginning
Omitting second index goes to end
fruit[:]
creates a copy of the entire string
Additional examples with omitted indices:
s = "Hello, World!"
print(s[:5]) # "Hello" (start omitted, defaults to 0)
print(s[7:]) # "World!" (end omitted, goes to end)
print(s[:]) # "Hello, World!" (copy of entire string)
2.6.1.5. Strings are Immutable¶
You cannot change an existing string. The best you can do is create a new string that is a variation on the original:
greeting = 'Hello, world!'
# This will raise an error:
# greeting[0] = 'J'
# Instead, create a new string:
new_greeting = 'J' + greeting[1:]
2.6.1.6. String Methods¶
Strings provide various built-in methods:
word = 'banana'
new_word = word.upper() # Convert to uppercase
# find method
index = word.find('na') # Find substring
index = word.find('na', 3) # Find substring starting at index 3
index = word.find('na', 3, 5) # Find substring between indices 3 and 5
String replacement (useful since strings are immutable):
greeting = "Hello, world!"
new_greeting = greeting.replace("Hello", "Hi") # Creates new string "Hi, world!"
2.6.1.7. The in
Operator¶
The in
operator is a boolean operator that returns True if first string appears as substring in second:
'a' in 'banana' # Returns True
'seed' in 'banana' # Returns False
2.6.1.8. String Comparison¶
Relational operators work on strings:
word = 'Pineapple'
if word < 'banana':
print('Your word comes before banana.')
elif word > 'banana':
print('Your word comes after banana.')
Note: Python handles uppercase and lowercase letters differently: all uppercase letters come before lowercase letters.
2.6.2. Lists¶
2.6.2.1. Lists as Sequences¶
A list is a sequence of values of any type:
numbers = [10, 20, 30, 40]
strings = ['crunchy frog', 'ram bladder', 'lark vomit']
mixed = ['spam', 2.0, 5, [10, 20]] # Nested list
empty = []
Using list comprehensions for more concise list traversal:
# Instead of:
squares = []
for x in range(10):
squares.append(x**2)
# Use list comprehension:
squares = [x**2 for x in range(10)]
2.6.2.2. Lists are Mutable¶
Unlike strings, lists are mutable. You can change elements using the bracket operator:
numbers = [42, 123]
numbers[1] = 5 # List is now [42, 5]
List indices work the same way as string indices:
Any integer expression can be an index
Out of range indices raise IndexError
Negative indices count from the end
2.6.2.3. List Traversal¶
Common ways to traverse lists:
# Method 1: Process elements
for cheese in cheeses:
print(cheese)
# Method 2: Process indices
for i in range(len(numbers)):
numbers[i] = numbers[i] * 2
2.6.2.4. List Operations¶
Lists support concatenation and repetition:
a = [1, 2, 3]
b = [4, 5, 6]
c = a + b # Concatenation
d = [0] * 4 # Repetition
e = [1, 2, 3] * 3 # More repetition
2.6.2.5. List Slices¶
The slice operator works on lists similar to strings:
t = ['a', 'b', 'c', 'd', 'e', 'f']
t[1:3] # Gets ['b', 'c']
t[:4] # Gets ['a', 'b', 'c', 'd']
t[:] # Creates a copy of the whole list
You can also update multiple elements using slices:
t[1:3] = ['x', 'y']
2.6.2.6. List Methods¶
Common list methods:
t = ['a', 'b', 'c']
t.append('d') # Add single element
t.extend(['e', 'f']) # Add multiple elements
t.sort() # Sort in place
# Removing elements
x = t.pop(1) # Remove and return element at index
t.remove('b') # Remove specific value
del t[1] # Delete element at index
del t[1:5] # Delete slice
2.6.2.7. Map, Filter, and Reduce¶
Common list operations patterns:
# Reduce - combine elements
def add_all(t):
total = 0
for x in t:
total += x
return total
# Map - transform elements
def capitalize_all(t):
res = []
for s in t:
res.append(s.capitalize())
return res
# Filter - select elements
def only_upper(t):
res = []
for s in t:
if s.isupper():
res.append(s)
return res
2.6.2.8. Lists and Strings¶
Converting between strings and lists:
# String to list of characters
s = 'spam'
t = list(s)
# String to list of words
s = 'pining for the fjords'
t = s.split()
# List to string
t = ['pining', 'for', 'the', 'fjords']
s = ' '.join(t)
2.6.2.9. Objects and Values¶
Two variables can refer to the same object (aliasing) or different objects with the same value:
a = [1, 2, 3]
b = [1, 2, 3] # Different object, same value
c = a # Same object (alias)
# Test identity
a is b # False
a is c # True
2.6.2.10. List Arguments¶
When you pass a list to a function, the function gets a reference to the list:
def delete_head(t):
del t[0] # Modifies original list
def tail(t):
return t[1:] # Returns new list
2.6.3. Dictionaries¶
2.6.3.1. Dictionaries as Mappings¶
A dictionary maps keys to values:
eng2sp = dict() # Empty dictionary
eng2sp['one'] = 'uno' # Add key-value pair
eng2sp = {'one': 'uno', 'two': 'dos', 'three': 'tres'} # Create with items
Dictionary features:
Keys must be hashable (immutable)
Values can be any type
Each key maps to exactly one value
Order is preserved (Python 3.7+)
Performance considerations:
List searches: \(O(n)\) (linear search required)
Dictionary lookups: \(O(1)\) (hash-based retrieval)
Nested dictionaries are useful for complex data structures:
students = {
"Alice": {"age": 21, "major": "CS"},
"Bob": {"age": 22, "major": "Math"}
}
print(students["Alice"]["major"]) # Output: "CS"
2.6.3.2. Dictionary Operations¶
Common operations:
# Length
len(eng2sp)
# Membership testing (keys only)
'one' in eng2sp
# Access values
eng2sp['two'] # Direct access
eng2sp.get('four', 0) # Access with default
2.6.3.3. Counters¶
Dictionaries are useful for counting:
def histogram(s):
d = dict()
for c in s:
if c not in d:
d[c] = 1
else:
d[c] += 1
return d
2.6.3.4. Dictionary Traversal¶
Ways to process dictionaries:
# Traverse keys
for c in h:
print(c, h[c])
# Traverse in sorted order
for key in sorted(h):
print(key, h[key])
2.6.3.5. Reverse Lookup¶
Finding a key based on a value:
def reverse_lookup(d, v):
for k in d:
if d[k] == v:
return k
raise LookupError('value not found')
2.6.3.6. Dictionaries and Lists¶
Lists can be dictionary values but not keys:
def invert_dict(d):
inverse = dict()
for key in d:
val = d[key]
if val not in inverse:
inverse[val] = [key]
else:
inverse[val].append(key)
return inverse
2.6.4. Best Practices¶
Choose appropriate data structures:
Strings for text data
Lists for ordered sequences
Dictionaries for key-value mappings
Remember mutability:
Strings are immutable
Lists are mutable
Dictionary values are mutable, keys must be immutable
Consider performance:
Dictionary lookups are fast
List searches are linear time
String operations create new strings
Use built-in methods when available:
String methods for text processing
List methods for sequence operations
Dictionary methods for mapping operations