Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
497 views

Super Advanced Python PDF

This document provides a 3-part summary of a presentation on advanced Python concepts: Part 1 discusses Python objects and sets, including set operations like union, intersection, difference, and symmetric difference. Part 2 covers list, dict, and lambda comprehensions as well as functions like map, filter, reduce, zip, and enumerate. Part 3 explains closures, decorators, generators, and the itertools library, highlighting functions like chain, combinations, permutations, and cycle.

Uploaded by

Shreyas Waghmare
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
497 views

Super Advanced Python PDF

This document provides a 3-part summary of a presentation on advanced Python concepts: Part 1 discusses Python objects and sets, including set operations like union, intersection, difference, and symmetric difference. Part 2 covers list, dict, and lambda comprehensions as well as functions like map, filter, reduce, zip, and enumerate. Part 3 explains closures, decorators, generators, and the itertools library, highlighting functions like chain, combinations, permutations, and cycle.

Uploaded by

Shreyas Waghmare
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 120

SuperAdvanced

Python
Warning:ThisTalkAttractsZombies
Presented by Raymond Chandler III / @raymondchandler
AShameless
Plug
ACT1
CritcalPoint#1
Everythingisanobject!
WhatisaSet?
CriticalPoint#2
EverythinginPythoncanbe
groupedintoaset!
WhatisSet
Theory?
Abranchofmathematicsthat
definesrulesandoperations
forworkingwithSets
BasicSet
Concepts
UnionAB
IfmemberofA,B,orBoth
list_a = ['a', 'b', 'c']
list_b = ['b', 'd', 'c']

print(set(a) | set(b))
>>> set(['a', 'c', 'b', 'd'])
IntersectAnB
OnlyifmemberofBoth
list_a = ['a', 'b', 'c']
list_b = ['b', 'd', 'c']

print(set(a) & set(b))


>>> set(['c', 'b'])
SetDiffA\B
Ifit'samemberofA,butnot
MemberofB
s.symmetric_difference(t) s^t

list_a = ['a', 'b', 'c']


list_b = ['b', 'd', 'c']

print(set(a) - set(b))
>>> set(['a'])

print(set(b) - set(a))
>>> set(['d'])
SymmetricDiff
ABorAB
IfmemberofAorBbutNOT
Both(XOR)
list_a = ['a', 'b', 'c']
list_b = ['b', 'd', 'c']

print(set(a) ^ set(b))
>>> set(['a', 'd'])
Cartesian
Product-AxB
PairsthefirstelementofA
withthefirstelementofB
from itertools import product
list_a = ['a', 'b', 'c']
list_b = ['b', 'd', 'c']

print(list(product(list_a, list_b)))
>>> [('a', 'b'), ('a', 'd'), ('a', 'c'), ('b', 'b'), ...]
Thinkofall
Python
collectionsas
Sets
Whatis
Category
Theory?
Thestudyof"morphisms".
Thetransitionsofsetsto
othersets.
Functors,
Functors,
Functors!
CriticalPoint#3
A"morphism"occurswhen
weapplyafunctortoaset
thattransformsitinto
somethingelse.
CriticalPoint#4
Foranysetwecanapply
somenumberoffunctorsto
arriveatANYotherset
ThePoint?
AnythinginPythoncanbe
transformedintoanything
elsebysimplyapplying
functorstosets
ACT2
ListComprehension
my_list = [1, 2, 3, 4, 5, 6]
print([x * 2 for x in my_list])
>>> [2, 4, 6, 8, 10, 12]
DictComprehension
my_dict = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6}
result = {k: v * 2 for k, v in my_dict}
print(result)
>>> {'a': 2, 'b': 4, 'c': 6, 'd': 8, 'e': 10, 'f': 12}
DictComprehension(cont.)
print(result.iterkeys())
>>> ['a', 'b', 'c', 'd', 'e', 'f']

print(result.itervalues())
>>> [2, 4, 6, 8, 10, 12]

print(result.iteritems())
>>> [('a', 2), ('b', 4), ('c', 6), ('d', 8), ('e', 10), ('f': 12)]
LambdaExpression
my_list = [1, 2, 3, 4, 5, 6]
def my_func(item):
return item * 2

print([my_func(x) for x in my_list])


>>> [2, 4, 6, 8, 10, 12]

other_func = lambda x: x * 2
print([other_func(x) for x in my_list])
>>> [2, 4, 6, 8, 10, 12]
Enumerate
my_first_list = ['a', 'b', 'c', 'd', 'e']
my_second_list = [1, 2, 3, 4, 5]
print(zip(my_first_list, my_second_list))
>>> [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)]

print(enumerate(my_first_list))
>>> [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd'), (4, 'e')]

print(enumerate(my_first_list, 3))
>>> [(3, 'a'), (4, 'b'), (5, 'c'), (6, 'd'), (7, 'e')]
Zip
my_first_list = ['a', 'b', 'c', 'd', 'e']
my_second_list = [1, 2, 3, 4, 5]
print(zip(my_first_list, my_second_list))
>>> [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)]

my_second_list = ['z', 'y', 'x', 'w', 'v']


print(zip(my_first_list, my_second_list))
>>> [('a', 'z'), ('b', 'y'), ('c', 'x'), ('d', 'w'), ('e', 'v')]
ComplexExamples
my_first_list = "abcde"
my_second_list = "zyxwv"
result = zip(my_first_list, my_second_list)
print(result)
>>> [('a', 'z'), ('b', 'y'), ('c', 'x'), ('d', 'w'), ('e', 'v')]

result2 = [''.join(x) for x in result]


print(result2)
>>> ['az', 'by', 'cx', 'dw', 'ev']
ComplexExamples(cont)
result = zip("abcde", "zyxwv")
print(dict(result))
>>> {'a': 'z', 'c': 'x', 'b': 'y', 'd': 'w'}

print(dict([(k * 3, v) for k, v in result]))


>>> {'aaa': 'z', 'bbb': 'y', 'ccc': 'x', 'ddd': 'w'}
The"filter"builtin
my_list = [1, 2, 3, 4, 5, 6]
print([x for x in my_list if x % 2 == 0])
>>> [2, 4, 6]

print(filter(lambda x: x % 2 == 0, my_list))
>>> [2, 4, 6]
The"any"and"all"builtins
my_list = [True, False, False, False]
print(any(my_list))
>>> True

print(all(my_list))
>>> False

my_list = [True, True, True]


print(all(my_list))
>>> True
The"map"builtin
my_list = range(1, 7)
print(my_list)
>>> [1, 2, 3, 4, 5, 6]

print([x * 2 for x in my_list])


>>> [2, 4, 6, 8, 10, 12]

print(map(lambda x: x * 2, my_list))
>>> [2, 4, 6, 8, 10, 12]
The"reduce"builtin
val = 0
for x in range(1, 7):
val += my_list
print(val)
>>> 21

print(reduce(lambda x, y: x + y, range(1, 7)))


>>> 21

print(reduce(lambda x, y: x * y, range(1, 7)))


>>> 720
The"sum"builtin
print(reduce(lambda x, y: x + y, range(1, 7)))
>>> 21

print(sum(range(1,7)))
>>> 21
ACT3
Whatisa
closure?
Aclosureisafunctionthat
wrapsaroundanother
functionandsomenumberof
variablesand'closesover'or
'traps'whatitcontainsinit's
ownscope.
Startwiththeinnerpart
def multiply_numbers(x, y):
return x * y

print(multiply_numbers(3, 5))
>>> 15
Wraptheinnerpart
def mult_closure(x):
def wrapped(y):
#wrapped closes over the 'x' variable
return x * y
return wrapped
ClosureExample
#this returns wrapped with 3 enclosed as 'x'
mult_by_three = mult_closure(3)

print(mult_by_three(5))
>>> 15
print(mult_by_three(10))
>>> 30
Closures(cont)
#this returns wrapped with 10 enclosed as 'x'
mult_by_ten = mult_closure(10)

print(mult_by_ten(5))
>>> 50
print(mult_by_ten(15))
>>> 150
Whentouseaclosure?
Great to DRY up code. Add Syntactic Sugar.
You need to write a complicated generator.
Monkey Patch a function you can't change.
Dynamically build behavior by 'stacking' functions.
MonkeyPatchExample
def bad_function_from_library(some_attr): #You didn't write this.
some_attr / 0 #Oh noes!

print(bad_function_from_library(10))
>>> ZeroDivisionError: integer division or modulo by zero
MonkeyPatch(cont.)
def dont_panic_closure(bad_func):
def wrapped(some_attr):
try:
bad_func(some_attr) #wrapped closes over bad_func
except:
print("The bad function unleashed Zombies!")
return wrapped

catch_it = dont_panic_closure(bad_function_from_library)
print(catch_it(10))
>>> The bad function unleashed Zombies!
Whatisa
decorator?
DecoratorExample
def dont_panic(bad_func):
def wrapped(some_attr):
try:
bad_func(some_attr) #wrapped closes over bad_func
except:
print("The bad function unleashed Zombies!")
return wrapped
DecoratorExample(cont.)
@dont_panic
def bad_function_i_wrote(some_attr): #You totally wrote this.
some_attr / 0 #Oh noes!

print(bad_function_i_wrote(10))
>>> The bad function unleashed Zombies!
@issyntacticsugarfor
closingoverafunction
Letslogit!
def logger(func_to_log):
def wrapped(*args, **kwargs):
print("Arguments were: %s, %s" % (args, kwargs))
func_to_log(*args, **kwargs) #call the real function
return wrapped

@logger
def my_func(x, y):
return x * y

print(my_func(10, 15))
>>> Arguments were (10, 15), {}
>>> 150
ACT4
Whatisthedifference
betweenanIteratoranda
Generator?
Abasicgenerator
def step(start=0, step=1):
_start = start
while True:
yield _start
_start += step

stepper = step(10, 2)
Abasicgenerator(cont.)
print(stepper.next())
>>> 10
print(stepper.next())
>>> 12
print(stepper.next())
>>> 14
yieldisboththeexitand
entrypointforthegenerator
Whatwilllist(stepper)do?
Letsfixthat
def step(start=0, step=1, end=50):
_start = start
while _start < end:
yield _start
_start += step
Letsfixthat(cont.)
stepper = step(10, 10)
print(list(stepper))
>>> [10, 20, 30, 40]
stepper = step(30, 5, 60)
print(list(stepper))
>>> [30, 35, 40, 45, 50, 55]
AGeneratorExpression
stepper = (x * 5 for x in range(0, 10))
print(list(stepper))
>>> [0, 5, 10, 15, 20, 25, 30, 35, 40, 45]
stepper = (x ** 2 for x in range(0, 5))
print(list(stepper))
>>> [0, 1, 4, 9, 16]
Lookfamiliar?
Whyusegenerators?
Work with large data sets
Don't need to hold the entire list in memory.
Processing data in realtime.
ACT5
The'itertools'
Library
chain(*seq)
from itertools import chain
list_a = ['a', 'b', 'c']
list_b = range(1,4)
print(list(chain(list_a, list_b))
>>> ['a', 'b', 'c', 1, 2, 3]
combinations
from itertools import combinations

my_list = 'abc'
print(list(combinations(my_list, 2))
>>> [('a', 'b'), ('a', 'c'), ('b', 'c')]

my_list = range(1,6)
print(list(combinations(my_list, 4))
>>> [(1, 2, 3, 4), (1, 2, 3, 5), (1, 2, 4, 5), (1, 3, 4, 5), (2, 3, 4, 5)]
permutations
from itertools import permutations

my_list = 'abc'
print(list(permutations(my_list, 2))
>>> [('a', 'b'), ('a', 'c'), ('b', 'a'),
>>> ('b', 'c'), ('c', 'a'), ('c', 'b')]

my_list = range(1,6)
print(list(permutations(my_list, 2))
>>> [(1, 2), (1, 3), (1, 4), (1, 5), (2, 1),
>>> (2, 3), (2, 4), (2, 5), (3, 1), (3, 2),
>>> (3, 4), (3, 5), (4, 1), (4, 2), (4, 3),
>>> (4, 5), (5, 1), (5, 2), (5, 3), (5, 4)]
compress
from itertools import compress

my_list = 'abcdef'
my_slectors = [1,0,1,1,0,1]
print(list(compress(my_list, my_selectors))
>>> ['a', 'c', 'd', 'e', 'f']

print([v for v, s in zip(my_list, my_selectors) if s])


>>> ['a', 'c', 'd', 'e', 'f']
count
from itertools import count

counter = count(1, 5)
for l in 'abc':
print(' '.join(l, str(counter.next())))
>>> a 1
>>> b 6
>>> c 11
cycle
from itertools import cycle

i_want_to_ride_my_bi = cycle('abc123')
print([i_want_to_ride_my_bi.next() for i in range(0,10)])
>>> ['a', 'b', 'c', 1, 2, 3, 'a', 'b', 'c']
groupby
from itertools import groupby

my_list='aaaaabbbbcccdd' #sorted
print(list(groupby(my_list)))
>>> [('a', <itertools._grouper object at 0x10fd76410>),
>>> ('b', <itertools._grouper object at 0x10fd76450>),
>>> ...
groupby(cont.)
print({k:list(v) for k, v in groupby(my_list)})
>>> {'a': ['a', 'a', 'a', 'a', 'a'],
>>> 'c': ['c', 'c', 'c'],
>>> 'b': ['b', 'b', 'b', 'b'],
>>> 'd': ['d', 'd']}
groupby(cont.)
my_list = [
{'id': 1, 'name': 'raymond'},
{'id': 1, 'name': 'bob'},
{'id': 2, 'name': 'sue'}]

print({k:list(v) for k, v in groupby(my_list,


key=lambda x: x['id')})
>>> {1: [{'id': 1, 'name': 'raymond'},
>>> {'id': 1, 'name': 'bob'}],
>>> 2: [{'id': 2, 'name': 'sue'}]}
groupby(cont.)
my_list = [
{'id': 1, 'name': 'raymond'},
{'id': 1, 'email': 'raymond@spkrbar.com'},
{'id': 2, 'name': 'sue'},
{'id': 2, 'email': 'sue@sallysue.com'}]

[ dict(
reduce(lambda y, z: y + z,
map(lambda x: x.items(), v)
)
) for k, v in groupby(my_list, key=lambda x: x['id']) ]
groupby(cont.)
>>> [{ 'email': 'raymond@spkrbar.com',
>>> 'id': 1,
>>> 'name': 'raymond'},
>>> { 'email': 'peggy@sue.com',
>>> 'id': 2,
>>> 'name': 'sue'}]
product
from itertools import product
list_a = 'abc'
list_b = [1, 2]

print(list(product(list_a, list_b)))
>>> [('a', '1'), ('a', '2'), ('b', '1'), ('b', '2'), ('c', '1'), ('c', '2')]

print({x[0]:x[1] for x in product(list_a, list_b)})


>>> {'a': '2', 'c': '2', 'b': '2'}
ifilter/imap/izip
Worksexactlylikefilter/map/zipexpectforonething.Whatis
it?
ACT6
Whatismetaprogramming?
Whatisintrospection?
Considerthis
class Swallow:
def __init__(self, airspeed, color):
self.airspeed = airspeed
self.color = color

unladen_bird = Swallow(34.2, 'black')


getattr
#Notice the attribute is a string
print(getattr(unladen_bird, 'airspeed'))
>>> 34.2
print(getattr(unladen_bird, 'color'))
>>> 'black'
print(getattr(unladen_bird, 'wingspan'))
>>> None
hasattr
#Notice the attribute is a string
print(hasattr(unladen_bird, 'airspeed'))
>>> True
print(hasattr(unladen_bird, 'wingspan'))
>>> False
setattr
#Notice the attribute is a string
print(getattr(unladen_bird, 'airspeed'))
>>> 34.2
setattr(unladen_bird, 'airspeed', 42)
print(getattr(unladen_bird, 'airspeed'))
>>> 42
setattr(cont.)
print(getattr(unladen_bird, 'wingspan'))
>>> None
setattr(unladen_bird, 'wingspan', 14)
>>> False
print(getattr(unladen_bird, 'wingspan'))
>>> 14
Thealmighty
type()
Rememberthis?
print(type(unladen_bird))
>>> <type 'instance'>

print(type(Swallow))
>>> <type 'classobj'>
print(Swallow.__class__)
>>> <type 'classobj'>

print(Swallow)
>>> <class __main__.Swallow at 0x1062a60b8>
print(unladen_bird.__class__)
>>> <class __main__.Swallow at 0x1062a60b8>
Whataboutthis?
print(type(unladen_bird.__class__))
>>> <type 'classobj'>

print(type(unladen_bird.__class)).__class__
>>> <type 'type'>
Wait...wat?
Huh?
print(type((35).__class__).__class__)
>>> <type 'type'>

print(type(('abc').__class__).__class__)
>>> <type 'type'>
Oh,Iknow.Becauseofthe
typekeyword?
print((35).__class__.__class__)
>>> <type 'type'>

print(('abc').__class__.__class__)
>>> <type 'type'>
Wat?
CriticalPoint#1
EverythingisanObject
Corollary
type()isPython'sGod
Object!
type(class_name,
parents[tuple],
attributes[dict])
type()creates
everything
Letscreateaclass
Bird = type('UnladenSwallow', (), {'airspeed': 42, 'wingspan': 15})
my_bird = Bird()

print(type(Bird))
>>> <type 'type'>
print(type(my_bird))
>>> <class '__main__.UnladenSwallow'>

print(my_bird.airspeed)
>>> 42
print(hasattr(my_bird, 'wingspan'))
>>> True
Whatisa
MetaClass?
Here'sahint
type()isaMetaClass
More
specifically...
AMetaClassisany
callable(functionorclass)
thatimplementstype's
functionsignature
Hereareacouple
Metaclasses
def my_meta_class(class_name, class_parents, class_attrs):
... do stuff
return type(class_name, class_parents, class_attrs)

class MyMetaclass(type):
def __new__(klass, class_name, class_parents, class_attrs):
... do stuff
return type.__new__(klass, class_name,
class_parents, class_attrs)
Whatcandoyouinthe'...do
stuff'part?
Look at the attributes
Set new attributes
Create functions dynamically
Traverse the parent classes
Change values in the class
type()creates
theclassnot
theinstance.
Sowhatdoesthisdo?
class ZombieKiller:
__metaclass__ = MyMetaClass
HeyPython,insteadofusing
type,usethisthinginstead!
Somerules...
#1Don'tusethem...ever
(unlessyouhaveto).
#2Ifyouarebuildinga
complicatedandhighly
dynamicAPIthen
metaclassesmaybeforyou.
#3Makeyourmetaclassa
class,notafunctionand
derivefromtype.
Whew!...
Ohshit...
Questions?

You might also like