SharedToo many formats.ipynbOpen in CoCalc
Managing strings and lists

Indices!

We can select an element with an index

numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(numbers[5])
5

We can also use a negative number to count from the end of the list

print(numbers[-1])
print(numbers[-4])
10 7

Repeated indecies can be used to retrieve data from lists with more than one dimension.

table = [
    [(0, 0), (0, 1), (0, 2)],
    [(1, 0), (1, 1), (1, 2)],
    [(2, 0), (2, 1), (2, 2)]
]

print(table[0][1])
(0, 1)

What will print(table[1][2][0]) show? How about print(table[0, 0, -1])?

print(numbers[2:4])
[2, 3]

Here the slice 2:4 means start at index 2 and keep going to, but not including, index 4.

What will print(numbers[2:2]) show?

In the slice a:b, both a and b are optional.

  • my_list[:b] is equivalent to my_list[0:b].
  • my_list[a:] is equivalent to my_list[a:len(my_list)]
  • what does my_list[:] do?

Given a two dimensional table ([[...]...), how would you select the last element of every row?

# Put into words what the following slices are doing
print(numbers[:-2])
print(numbers[2:-2])
print(numbers[-2:2])
print(numbers[-2:])
[0, 1, 2, 3, 4, 5, 6, 7, 8] [2, 3, 4, 5, 6, 7, 8] [] [9, 10]

Strings!

Concatinate them!

print('My ' + 'String')
My String

Convert to them, from them

print('My number: ' + str(54))
# walk through this example, and explain what each operator (+, str, int) is doing
# You might have to work from the most nested expression outwards
print('My number: ' + str(int('54') + 3))
My number: 54 My number: 57

Strings can be indexed and iterated over like a list.

element = 'oxygen'
for character in element:
    print(character)
o x y g e n
print('first three characters:', element[0:3])
print('last three characters:', element[3:6])
first three characters: oxy last three characters: gen

There are lots of excellent methods to work with strings:

  • split
  • join
  • strip
  • lower/upper
  • replace
  • startswith
comma_seperated_values = '1, 2, 3, 4'
list_values = comma_seperated_values.split(',')

print(list_values)
original_values = ','.join(list_values)
print(original_values)
['1', ' 2', ' 3', ' 4'] 1, 2, 3, 4

Challenge question: convert the string '1, 2, 3, 4' into the list of integers [1, 2, 3, 4]

num_list = []
for num in comma_seperated_values.split(','):
    num_list = num_list + [int(num.strip())]
    
print(num_list)
[1, 2, 3, 4]

String litterals help you write text with newlines in it.

poem = '''
hickory dickory dock
the mouse ran up the clock
'''

# poem is equivalent to 'hickory dickory dock\nthe mouse ran up the clock'
print(poem)
hickory dickory dock the mouse ran up the clock

Format Strings!

Python keeps reinventing string formatting, the latest is format strings (Python version >= 3.6)

name = 'Noisebridge'
print(f'Hello {name}')
Hello Noisebridge
print(f'Hello {1 + 1}')
Hello 2

Everything between the brackets in the format string is evaluated

print(f'Hello {name.upper()}!')
Hello NOISEBRIDGE!

Formatting options for everyone!

import math

name = 'Noisebridge'
my_name = 'Jared'

print(f'I love {math.pi} -> I love {math.pi * 10:.3}')
print(f'I love fixed width {name:^11}')
print(f'I love fixed width {my_name:^11}')
I love 3.141592653589793 -> I love 31.4 I love fixed width Noisebridge I love fixed width Jared

The previous preferred way of formatting strings was the .format method

name = 'Noisebridge'
print('Hello {0}!'.format(name))
Hello Noisebridge!

Always be careful with user input!

def generate_page(body):
    '''uh oh'''
    return f'<html><body>{body}</body></html>'

You can shoot yourself in the foot.

import sys
print(f'Hello {sys.exit()}')
An exception has occurred, use %tb to see the full traceback. SystemExit
/ext/anaconda5/lib/python3.6/site-packages/IPython/core/interactiveshell.py:2971: UserWarning: To exit: use 'exit', 'quit', or Ctrl-D. warn("To exit: use 'exit', 'quit', or Ctrl-D.", stacklevel=1)

You can get pretty silly with these

format_string = 'format string'
# Haha
print(f"Hello {f'{format_string}'.upper()}")
Hello FORMAT STRING

We have fun here

Regular Expressions!

import re
re_digit = re.compile('\d')
match = re_digit.match('1')
if match is not None:
    print(match.group())
1

Special characters in regular expressions:

  • \d any digit
  • \ escape
  • . any single character
  • * between 0 and infinite repetitions of the previous character
  • + between 1 and infinite repetitions of the previous character
  • ? between 0 and 1 repetitions of the previous character
  • {i,j} between i and j repetitions of the previous character
  • () group that can be operated on, or referenced later with \1 ... \9
  • lots more ...

Lets make a regular expression that matches a phone number!

[n^2 for n in range(10)]