KEMBAR78
Python Tidbits | PPTX
Python Tidbits
Mitchell Vitez
● Learn new constructs
● Play with them in the interpreter
● Learn how to apply them to your own code
● Become a better Python programmer
Goals
import this
import antigravity
from __future__ import braces
if condition:
pass
#{
#}
# -*- coding: rot13 -*-
cevag 'Clguba vf sha!'
Chained comparisons
if 12 < x < 144:
print x
3 != x < y == 24 < z < 1000 > pi
Swapping
Temporary Variable
a, b = 1, 2
temp = a
a = b
b = temp
XOR
a, b = 1, 2
a ^= b
b ^= a
a ^= b
Problem
a, b = 'Python', 'Tidbits'
Solution
a, b = b, a
Tuple packing
a, b = 'it will', 'consume you'
a, b = b, a
(a, b) = (b, a)
(a, b) = ('consume you', 'it will')
temp = a
a = b
b = temp
a, b = b, a
point = (1, 2, 3)
x, y, z = point
nums = 1, 2, 3, 4, 5
sum(nums)
Slices
[start:end:step]
'Michigan Hackers'[6:13]
'Michigan Hackers'[6:13]
0123456789abcdef
'Michigan Hackers'[:-5]
0123456789abcdef
'Michigan Hackers'[-5:]
0123456789abcdef
'Michigan Hackers'[::2]
0123456789abcdef
[::-1]
reversed()
List comprehensions
Make a list of cubes
of the first 100
numbers
Imperative
cubes = []
for x in range(100):
cubes.append(x ** 3)
Functional
cubes = map(lambda x: x ** 3, range(100))
List comprehension
cubes = [x ** 3 for x in range(100)]
With a predicate
cubes = []
for x in range(100):
if x % 2:
cubes.append(x ** 3)
cubes = map(lambda x: x ** 3,
filter(lambda x: x % 2, range(100)))
cubes = [x ** 3 for x in range(100) if x % 2]
cubes = [x ** 3 for x in range(100)][1::2]
Sum of two dice
table = []
for i in range(1, 7):
row = []
for j in range(1, 7):
row.append(i + j)
table.append(row)
[[i + j for i in range(1, 7)]
for j in range(1, 7)]
word = 'abracadabra'
[word[:i] for i in range(len(word), 0, -1)]
Splat operator
Named arguments
def increase(num, how_much=1, multiply=False):
if multiply:
return num * how_much
return num + how_much
increase(1)
increase(10, 10, False)
increase(25, multiply=True, how_much=2)
Unpack dictionaries to arguments
options = {
'is_the_splab_door_open': True,
'is_it_hack_night_yet': False,
'students_enrolled_at_umich': 43651,
'fishythefish_status': 'savage'
}
func(**options)
Unpack argument lists
def add(a, b):
return a + b
nums = [1, 2]
add(*nums)
Variadic functions
def sum(*nums):
result = 0
for num in nums:
result += num
return result
sum(1, 2, 3, 4)
Args and kwargs
def function(arg1, arg2, *args, **kwargs):
pass
Decomposition
x, xs = things[0], things[1:]
x, *xs = things
Iterators
for _ in _
for item in list
for character in string
for key in dictionary
for line in file
__iter__
nums = [1, 2, 3, 4, 5]
iterator = iter(nums)
iterator.next()
Implementing range
class simple_range:
def __init__(self, n):
self.n = n
self.data = [i for i in range(n)]
def __iter__(self):
return iter(self.data)
Performance
import time
class simple_range:
def __init__(self, n):
t0 = time.time()
self.n = n
self.data = [i for i in range(n)]
print 'Time taken:', time.time() - t0
def __iter__(self):
return iter(self.data)
simple_range(100000000)
# Time taken: 7.59687685966
Improved Performance
class simple_range:
def __init__(self, n):
self.n = n
self.i = 0
def __iter__(self):
return self
def next(self):
if self.i < self.n:
result = self.i
self.i += 1
return result
else:
raise StopIteration()
range, xrange, Python 3 range
simple_range(100000000)
# Time taken: 7.59687685966
# Time taken: 0.00002408027
Generators
Functions returning sequences
def simple_range(n):
i = 0
while i < n:
yield i
i += 1
yielding
Generator expressions
cubes = (x ** 3 for x in range(100))
How many 3-letter strings are
alphabetically between 'foo' and 'bar'?
A more complicated generator
def alphagen(start, end=None):
s = list(reversed(start))
while end is None or s != list(reversed(end)):
yield ''.join(reversed(s))
if s == list('z' * len(s)):
s = list('a' * (len(s) + 1))
else:
for i, ch in enumerate(s):
if ch is 'z':
s[i] = 'a'
else:
s[i] = chr(ord(ch) + 1)
break
Solution
i = 0
for a in alphagen('bar', 'foo'):
i += 1
print i - 1
# Time taken to create generator: .00000596046
Decorators
Tracing
def fibonacci(n):
t0 = time.time()
print 'fib started'
if n is 0 or n is 1:
print 'fib finished in', time.time() - t0,
'seconds returning', 1
return 1
else:
x = fibonacci(n - 1) + fibonacci(n - 2)
print 'fib finished in', time.time() - t0,
'seconds returning', x
return x
Tracing
def trace(f):
def f_prime(n):
t0 = time.time()
print f.__name__, 'started'
value = f(n)
print f.__name__, 'finished in', time.time() -
t0, 'seconds returning', value
return value
return f_prime
def fibonacci(n):
if n is 0 or n is 1:
return 1
else:
return fibonacci(n - 1) + fibonacci(n - 2)
fibonacci = trace(fibonacci)
Syntactic sugar
@trace
def fibonacci(n):
if n is 0 or n is 1:
return 1
else:
return fibonacci(n - 1) + fibonacci(n - 2)
Tidbits
s = u'Hallelujah Bovay Alabama Δ'
words = s.split()
s = ', '.join(words)
print s
' '.join([''.join(reversed(word)) for word in s.split()])
' '.join(reversed(s.split()))
reversed(s)
import random
random.choice(['Ankit', 'Abby', 'Edward',
'Andrew', 'Omkar', 'Jason'])
Interested in more? Check out these
dis
pdb
flask
pydoc
pygame
itertools
functools
exec, eval
beautiful soup
dict comprehensions
Python Tidbits

Python Tidbits

Editor's Notes

  • #2 View the code at https://github.com/mitchellvitez/Python-Tidbits
  • #14 TypeError: unsupported operand type(s) for ^=: 'str' and 'str'