[]

Project Euler Workshop / Intermediate Python Operations

# PythonPH August 2014

Fork this iPython notebook via GitHub. Follow @stefsy on Twitter and I'll answer any questions I can.

Topics

Array Slicing

In [24]:
array = [0,1,2,3,4,5,6,7,8,9,10]

# accessing elements by index value
print array[0]
print array[1]
0
1

In [25]:
# What's the value of len(array) ? 
print len(array)
11

In [26]:
# also works for strings
also_a = "Ninoy Aquino"

print also_a[0]
print also_a[4]
N
y

In [27]:
# array slicing 
# array[ <start index> : <end index>]

print array[1:5]
print array[2:10]
[1, 2, 3, 4]
[2, 3, 4, 5, 6, 7, 8, 9]

In [28]:
# negative values acceptable

print array[0:-1]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

In [29]:
# empty start & end values have a meaning

print array[4:]
print array[:2]
[4, 5, 6, 7, 8, 9, 10]
[0, 1]

In [30]:
# What would this do? 

print array[:]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

In [31]:
# array slicing part 2
# array[<start>:<end>:<step>]

print array[::1]
print array[::2]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[0, 2, 4, 6, 8, 10]

In [32]:
# What does this do? 

print array[::-1]
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

In [33]:
# RECAP
# array[<start>:<end>:<step>]

# gets the first half of the array 
print array[:len(array)/2]

# quickly reverses the array 
print also_a[::-1]
[0, 1, 2, 3, 4]
oniuqA yoniN

In [34]:
# watch out for this gotcha
# instead of printing out reverse of the first 3 chars, 
# python reverses first, then prints from last character to character at index 3

print also_a[:3:-1]
oniuqA y

In [35]:
# if you want to print out reverse of first 3 chars, do this instead

print also_a[:3][::-1]
niN

List comprehension

elegant way of constructing lists w/o for loops

In [36]:
x = []
for i in range(0,10):
    x.append(i+5)

y = [i+5 for i in range(0,10)]

print x == y
True

Never write a nested for loop again!

In [37]:
nest = []
for m in range(5,10):
    for n in range(1,8):
        nest.append(m*n**2)

comp = [m*n**2 for m in range(5,10) for n in range(1,8)]

print nest == comp
True

In [38]:
# works with if statements too
comp = [(m,n) for m in range(1,5) for n in range(1,10) if m%2 == 0 and n%3 ==0 ]

print comp
[(2, 3), (2, 6), (2, 9), (4, 3), (4, 6), (4, 9)]

Enumerate

In [39]:
fruits = ['mango','banana','pineapple','guava','papaya']

# not very pythonic approach
for i in range(0,len(fruits)):
    print i, fruits[i]
0 mango
1 banana
2 pineapple
3 guava
4 papaya

In [40]:
# enumerate is a handy built in function that counts for you!
for fruit in enumerate(fruits):
    print fruit
(0, 'mango')
(1, 'banana')
(2, 'pineapple')
(3, 'guava')
(4, 'papaya')

In [41]:
for i, fruit in enumerate(fruits):
    print i, fruit
0 mango
1 banana
2 pineapple
3 guava
4 papaya

Itertools : Combinations and Permutations

Combinations -- how many way to select a subset of elements from a set

Permutations -- how many ways to reorder a set of elements

In [42]:
import itertools


# combinations(set,number in subset)
for c in itertools.combinations([1,2,3,4,5], 2):
    print c
(1, 2)
(1, 3)
(1, 4)
(1, 5)
(2, 3)
(2, 4)
(2, 5)
(3, 4)
(3, 5)
(4, 5)

In [43]:
# permutations(set) 

for word in itertools.permutations('ant'):
    print "".join(word)
ant
atn
nat
nta
tan
tna

Sets

A huge help for optimizing code performance. e.g. going over lists when checking to see if item x already exists.

Checking to see if X in S takes O(n) time if S is a list, but O(1) time if S is a set. This is actually a problem when you're working with hundreds of thousands of numbers.

More on time complexity

A set is an unordered collection of unique elements.

What does that mean?

In [44]:
# initialize a set like so
s = set()
In [45]:
for char in "Philippines":
    s.add(char)

print s
set(['e', 'p', 'i', 'h', 'l', 'n', 'P', 's'])

In [46]:
# useful for checking unique values in a list too!
print len("Philippines")
print len(s)
11
8

In [47]:
# set operations are amazing. 
my_shows = set(['Modern Family', 'Veep', 'Hannibal', 'Fargo'])
your_shows = set(['Modern Family','Revolution','The 100','Hannibal','True Blood','Teen Wolf'])
In [48]:
# intersection 
print my_shows & your_shows
set(['Hannibal', 'Modern Family'])

In [49]:
# union
print my_shows | your_shows
set(['Revolution', 'Veep', 'Teen Wolf', 'Modern Family', 'True Blood', 'The 100', 'Fargo', 'Hannibal'])

In [50]:
# in set a but not in set b 
print your_shows - my_shows
set(['True Blood', 'Revolution', 'Teen Wolf', 'The 100'])

Project Euler

These are all really handy tools for tackling Project Euler problems! Break into teams, and start tackling these. The PythonPH folks will be floating around answering questions.