Python Tidbits

63
Python Tidbits Mitchell Vitez

Transcript of Python Tidbits

Python TidbitsMitchell 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 = aa = bb = temp

XOR

a, b = 1, 2

a ^= bb ^= aa ^= 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 = aa = bb = temp

a, b = b, a

point = (1, 2, 3)x, y, z = point

nums = 1, 2, 3, 4, 5sum(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 predicatecubes = []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)

Performanceimport 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 Performanceclass 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 generatordef 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

Tracingdef 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

Tracingdef 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

@tracedef 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 thesedispdb

flaskpydocpygame

itertoolsfunctoolsexec, eval

beautiful soupdict comprehensions