Go to: Na-Rae Han's home page  

Python 3 Notes

        [ HOME | LING 1330/2330 ]

String Methods Part 2

<< Previous Note           Next Note >>
On this page: .index(), .rindex(), .find(), .rfind(), .isalpha(), .isalnum(), .isdigit(), .isspace(), .islower(), .isupper(), string formatting f'{}'.

Locating a Substring

There is a group of string methods whose function is to return the location of a certain substring: .index(), .rindex(), .find() and .rfind().

Below, .index() returns the index of the first substring found within the string, starting from the left edge:
 
>>> 'green ideas'.index('e') 
2 
>>> 'green ideas'.index('id') 
6
.rindex() is the mirror opposite; it searches from the right edge.
 
>>> 'green ideas'.rindex('e') 
8 
But what if the substring is not found? In such an event, .index() and .rindex() produces an error. Therefore, unless you're sure, it's a good idea to use an in substring test as the precondition:
 
>>> phrase = 'green ideas'
>>> phrase.index('th') 
Traceback (most recent call last):
  File "<pyshell#24>", line 1, in <module>
    phrase.index('th')
ValueError: substring not found  
>>> if 'th' in phrase:
        print(phrase.index('th'))    # nothing prints, but error is avoided

>>> 		
That's where .find() and .rfind() differ from .index() and .rindex(): if the substring is not found, they return -1 instead of producing an error. They behave exactly like .index() and .rindex() otherwise.
 
>>> 'green ideas'.find('e') 
2 
>>> 'green ideas'.rfind('e') 
8
>>> 'green ideas'.find('th')     # No 'th'! Returns -1
-1

Is Every Character ... ?

Some string methods test a string on whether or not every character in it possesses a certain property. For example, .isalpha() returns True if and only if every character in the string is alphabetic, i.e., in a-z or A-Z:
 
>>> 'iPad'.isalpha() 
True 
>>> 'co-operate'.isalpha() 
False 
Below is a list of similar methods and examples. They all return True/False.
Method Is every character ...? Example
.isalpha() alphabetic (A-Z, a-z) See above

.isalnum()

alpha-numeric (A-Z, a-z, 0-9)
>>> 'Homework3'.isalnum() 
True 
>>> 'ice cream'.isalnum() 
False 

.isdigit()

numeric (0-9)
>>> '2014'.isdigit() 
True 
>>> '9:30'.isdigit() 
False 

.isspace()

whitespace character:
' ', '\n', '\t', '\r'
>>> '\n\t  \r  \n'.isspace() 
True 
>>> ' A b c 12 '.isspace() 
False 

.islower()

lowercase (a-z)
>>> 'apple'.islower() 
True 
>>> 'iPad'.islower() 
False 

.isupper()

uppercase (A-Z)
>>> 'HELLO'.isupper() 
True 
>>> 'Hello'.isupper() 
False 

String Formatting

Printing out a bunch of mixed data types can be cumbersome. Below, you're looking for the maximum price and the average price. But before concatenating them, you have to make sure to turn a number into a string, plus the average looks messy with a long trail of decimal digits:
 
>>> price = [12.50, 199, 5, 3.75, 33, 66]
>>> max(price)
199 
>>> sum(price)/len(price)
53.208333333333336 
>>> print('Top price: $' + str(max(price)) + " average: $" + str(sum(price)/len(price))) 
Top price: $199 average: $53.208333333333336 
Using string formatting with the f'{}' syntax makes things much neater. Inside the formatted string, you can insert a Python expression enclosed in {}. In addition, you can specify additional formatting syntax: {:.2f} means round the number to the 2nd decimal digit.
 
>>> print(f'Top price: ${max(price)} average: ${sum(price)/len(price):.2f}')
Top price: $199 average: $53.21 
Similarly, you can pad digits. Below, we want to print out the date 'Jan 3' as 'Jan 03'. This is accomplished by '{:02d}' which pads 0 on the left to the desired width of 2.
 
>>> dates = [('Jan',3), ('Jan',15), ('Mar',7), ('Apr',22)]
>>> for (mo,day) in dates:
        print(f'{mo} {day:02d}')
Jan 03
Jan 15
Mar 07
Apr 22 
>>>