Last active
August 29, 2015 13:58
-
-
Save bjdixon/10297261 to your computer and use it in GitHub Desktop.
Beautiful, Idiomatic Python or Don't do this, do this - Raymond Hettinger presentation (pycon 2013)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Replace traditional index manipulation with Python’s core looping idioms. | |
Learn advanced techniques with for-else clauses and the two argument form of iter(). | |
Clarify function calls with keyword arguments. | |
Tuple packing and unpacking | |
Don’t under‐estimate the advantages of updating state variables at the same time. It eliminates an entire class of errors due to outof-order updates. It allows high level thinking: “chunking”. | |
Decorators and Context Managers | |
Helps separate business logic from administrative logic. Clean, beautiful tools for factoring code and improving code reuse. Good naming is essential. | |
Factor out temporary contexts by using "with" instead of "try/finally". | |
One logical line of code equals one sentence in English. | |
Looping over a range of numbers | |
------------------------------- | |
Don't do this | |
for i in [0, 1, 2, 3, 4, 5]: | |
print i**2 | |
Do this | |
for i in range(6): | |
print i**2 | |
Looping over a collection | |
-------------------------- | |
colors = ['red', 'green', 'blue', 'yellow'] | |
Don't do this | |
for i in range(len(colors)): | |
print colors[i] | |
Do this instead | |
for color in colors: | |
print color | |
(Reversed) | |
Don't do this | |
for i in range(len(colors)-1, -1, -1): | |
print colors[i] | |
Do this instead | |
for color in reversed(colors): | |
print color | |
Looping over a collection and indicies | |
-------------------------------------- | |
Don't do this | |
for i in range(len(colors)): | |
print i, '-->', colors[i] | |
Do this instead | |
for i, color in enumerate(colors): | |
print i, '-->', color | |
Looping over two collections | |
---------------------------- | |
names = ['raymond', 'rachel', 'matthew'] | |
colors = ['red', 'green', 'blue', 'yellow'] | |
for name, color in izip(names, colors): | |
print name, '-->', color | |
(Construct a dictionary from these pairs | |
d = dict(izip(names, colors)) | |
{'matthew': 'blue', 'rachel': 'green', 'raymond': 'red'} | |
d = dict(enumerate(names)) | |
{0: 'raymond', 1: 'rachel', 2: 'matthew'} | |
Looping in sorted order | |
----------------------- | |
colors = ['red', 'green', 'blue', 'yellow'] | |
for color in sorted(colors): | |
print color | |
for color in sorted(colors, reverse=True): | |
print color | |
Custom sort order | |
----------------- | |
colors = ['red', 'green', 'blue', 'yellow'] | |
Don't do this | |
def compare_length(c1, c2): | |
if len(c1) < len(c2): return -1 | |
if len(c1) > len(c2): return 1 | |
return 0 | |
print sorted(colors, cmp=compare_length) | |
Do this | |
print sorted(colors, key=len) | |
Multiple exit points in loops | |
----------------------------- | |
Don't do this | |
def find(seq, target): | |
found = False | |
for i, value in enumerate(seq): | |
if value == tgt: | |
found = True | |
break | |
if not found: | |
return -1 | |
return i | |
Do this | |
def find(seq, target): | |
for i, value in enumerate(seq): | |
if value == tgt: | |
break | |
else: | |
return -1 | |
return i | |
Looping over dictionary keys | |
---------------------------- | |
d = {'matthew': 'blue', 'rachel': 'green', 'raymond': 'red'} | |
Don't do this | |
for k in d: | |
print k | |
Or this | |
for k in d.keys(): | |
if k.startswith('r'): | |
del d[k] | |
Do this | |
d = {k : d[k] for k in d if not k.startswith('r')} | |
Looping over a dictionary keys and values | |
----------------------------------------- | |
Don't do this | |
for k in d: | |
print k, '-->', d[k] | |
Or this | |
for k, v in d.items(): | |
print k, '-->', v | |
Do this | |
for k, v in d.iteritems(): | |
print k, '-->', v | |
Counting with dictionaries | |
-------------------------- | |
colors = ['red', 'green', 'red', 'blue', 'green', 'red'] | |
Don't do this | |
d = {} | |
for color in colors: | |
if color not in d: | |
d[color] = 0 | |
d[color] += 1 | |
{'blue': 1, 'green': 2, 'red': 3} | |
Or this | |
d = {} | |
for color in colors: | |
d[color] = d.get(color, 0) + 1 | |
Do this | |
d = defaultdict(int) | |
for color in colors: | |
d[color] += 1 | |
List Comprehensions and Generator Expressions | |
--------------------------------------------- | |
Don't do this | |
result = [] | |
for i in range(10): | |
s = i ** 2 | |
result.append(s) | |
print sum(result) | |
Do this | |
print sum(i**2 for i in xrange(10)) | |
Unpacking sequences | |
------------------- | |
p = 'Raymond', 'Hettinger', 0x30, '[email protected]' | |
Don't do this | |
fname = p[0] | |
lname = p[1] | |
age = p[2] | |
email = p[3] | |
Do this | |
fname, lname, age, email = p | |
Updating multiple state variables | |
--------------------------------- | |
Don't do this | |
def fibonacci(n): | |
x = 0 | |
y = 1 | |
for i in range(n): | |
print x | |
t = y | |
y = x + y | |
x = t | |
Do this | |
def fibonacci(n): | |
x, y = 0, 1 | |
for i in range(n): | |
print x | |
x, y = y, x+y |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment