Strings (Iteration & Manipulation)
Basic syntax and examples.
Basic Iteration
The following three pieces of code all do the same thing (printing the characters of the string, each on a separate line).
course = 'Introduction'
for c in course:
print(c)
course = 'Introduction'
for i in range(len(course)):
print(course[i])
course = 'Introduction'
i = 0
while i < len(course):
print(course[i])
i += 1
The first piece of code is pythonic, but the other two are not. while the three pieces of code all work fine, any professional Python programmer would cringe at the sight of the second and third pieces of code! Nevertheless, we include them here because they are important for examples you will see later on.
Debugging
The following code attempts to print the course name in reverse. However, it has bugs. What are they?
course = 'Introduction'
for i in range(len(course), 0, -1):
print(course[i])
Answer
- The range should start at
len(course) - 1. Otherwise we will get anIndexError. - The range should end at
-1. Otherwise we will not see the character at index0.
Note that the easiest way to iterate over the characters of the string in reverse order is as follows:
for c in course[::-1]:
print(c)
Application 1: Palindromes
A palindrome is a string that can be read left-to-right or right-to-left. The following are examples of palindromes and non-palindromes:
Palindromes. a, bb, bab, abccba, karak, madam, level.
Non-Palindromes. ab, abcdabcd, ABCcba, hello.
We would like to write a function that checks if a given string is a palindrome. To do this, we will use two variables:
i: Goes through the indices left to right.j: Goes right-to-left.
At each iteration, we will check if if the character at i is the same as the character j or not. We stop if either the characters are different (the string is not a palindrome), or if i and j reach or cross each other.
def is_palindrome(s):
i = 0
j = len(s)-1
while i < j:
if s[i] != s[j]:
return False
i += 1
j -= 1
return True
Follow-up question 1. Can you write the above code using a for-loop?
Follow-up question 2. Can you write the above code using a single line?
Answer
Use return s == s[::-1] Application 2: Parsing Strings
Function find can be used to search for a string inside another string. It returns the index of the string we are searching for, unlike the in operator which returns either True or False. The following are examples:
# indices: 0123456789...
title = "The Prince and The Pauper"
print(title.find("Prince")) # 4
print(title.find("xyz")) # -1 (not found)
print(title.find("the")) # -1 (case-sensitive)
print(title.find("The")) # 0 (first occurrence)
print(title.find("and")) # 11
print(title.find(" ")) # 3 (first space)
We will use this function in the following application: Read emails for 10 people and verify if they belong to Jordanian domains.
Note that every email has the @ character, and every Jordanian email ends with .jo. Read and understand the following code:
for i in range(1, 11):
email = input("Enter your email " + str(i) + ": ").lower()
# pos_at < 0 ----> No @ in email
# pos_at = 0 ----> email begins with @
pos_at = email.find('@')
if pos_at <= 0:
print("ERROR: Invalid jordanian email")
continue
domain = email[pos_at + 1:]
pos_dot = domain.find('.jo')
# pos_dot < 0 -----> no .jo after @
# pos_dot = 0 -----> .jo right after @
if pos_dot <= 0:
print("ERROR: Invalid jordanian email")
continue
# extract the domain name without .jo
print(domain[: pos_dot], "is a valid jordanian domain.")