Beautiful Python
Alicia Pérez
www.stylesage.co
Accent?
We are flying!
>>> import antigravity
Strings
colors = ['red', 'blue', 'green', 'yellow']
result = ''
for s in colors:
result += s
# result: 'redbluegreenyellow'
colors = ['red', 'blue', 'green', 'yellow']
result = ''.join(colors)
# result: 'redbluegreenyellow'
Good
Bad
Create a string from a list
Strings
colors = ['red', 'blue', 'green', 'yellow']
result = ''
for s in colors:
result += s + ','
result = result[:-1]
# result: 'red,blue,green,yellow'
colors = ['red', 'blue', 'green', 'yellow']
result = ','.join(colors)
# result: 'red,blue,green,yellow'
Good
Bad
Create a string from a list joined by comma
Strings
my_very_big_string = """For a long time I used to go to bed early. Sometimes,
when I had put out my candle, my eyes would close so quickly that I had not even
time to say "Im going to sleep."""
my_very_big_string = (
"For a long time I used to go to bed early. Sometimes, "
"when I had put out my candle, my eyes would close so quickly "
"that I had not even time to say: Im going to sleep."
)
Good
Bad
Multi-line
Strings
contains?
stylesage = 'Fashion meets Big Data'
if stylesage.contains('Fashion'):
pass
Bad
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'contains'
Strings
stylesage = 'Fashion meets Big Data'
if stylesage.find("Fashion") != -1:
pass
Good
Bad
stylesage = 'Fashion meets Big Data'
if 'Fashion' in stylesage:
pass
contains in
Strings
format
# OR
'%s %s' % ('one', 'two') '%d %d' % (1, 2)
# output: 'one two' # output: '1 2'
New
Old
# OR
'{} {}'.format('one', 'two') '{} {}'.format(1, 2)
# output: 'one two' # output: '1 2'
Strings
Basic format
# OR
'%s %s' % ('one', 'two') '%d %d' % (1, 2)
# output: one two # output: 1 2
New
Old
# OR
'{} {}'.format('one', 'two') '{} {}'.format(1, 2)
# output: one two # output: one two
# explicit positional index
'{1} {0}'.format('one', 'two')
# output: two one
Strings
Padding and aligning
# OR
'%10s' % ('test',) '%-10s' % ('test',)
# output: ' test' # output: 'test '
New
Old
# OR
'{:>10}'.format('test') '{:10}'.format('test')
# output: ' test' # output: 'test '
Strings
Padding and aligning
# OR
'%10s' % ('test',) '%-10s' % ('test',)
# output: ' test' # output: 'test '
New
Old
# OR
'{:>10}'.format('test') '{:10}'.format('test')
# output: ' test' # output: 'test '
# choose the padding character
'{:_<10}'.format('test')
# output: 'test______'
Strings
Padding and aligning
# OR
'%10s' % ('test',) '%-10s' % ('test',)
# output: ' test' # output: 'test '
New
Old
# OR
'{:>10}'.format('test') '{:10}'.format('test')
# output: ' test' # output: 'test '
# choose the padding character
'{:_<10}'.format('test')
# output: 'test______'
# center align value
'{:_^10}'.format('test')
# output: '___test___'
Strings
Padding and aligning
New
# This operations are not available with old-style formatting
'{:=5d}'.format((- 23))
# output: '- 23'
'{:%Y-%m-%d %H:%M}'.format(datetime(2001, 2, 3, 4, 5))
# output: '2001-02-03 04:05'
person = {'first': 'Jean-Luc', 'last': 'Picard'}
'{p[first]} {p[last]}'.format(p=person)
# output: 'Jean-Luc Picard'
data = [4, 8, 15, 16, 23, 42]
'{d[4]} {d[5]}'.format(d=data)
# output: '23 42'
tu = (12,45,22222,103,6)
print '{0} {2} {1} {2} {3} {2} {4} {2}'.format(*tu)
# output: '12 22222 45 22222 103 22222 6 22222'
Booleans
if len(items) != 0:
pass
if name != "":
pass
Good
Bad
if items:
pass
if name:
pass
Check if variable equals a constant
False | True |
---|---|
False (== 0) | True (== 1) |
"" (empty string) | any string but "" (" ", "anything") |
0, 0.0 | any number but 0 (1, 0.1, -1, 3.14) |
[], (), {}, set() | any non-empty container ([0], (None,),['']) |
None | almost any object that's not explicitly False |
Booleans
Check if variable equals a constant
Booleans
if x >= start and x <= end:
# do stuff
Good
Bad
if start <= x <= end:
# do stuff
Chained comparisons
Comparisons
values = range(10)
i = 0
found = False
while not found and i < len(values):
found = not values[i] % 2
i += 1
Good
Bad
values = range(10)
anyPair = any([not value % 2 for value in values])
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# [True, False, True, False, True, False, True, False, True, False]
# anyPair: True
Any
Comparisons
values = range(10)
i = 0
allPairs = True
while allPairs and i < len(values):
allPairs = not values[i] % 2
i += 1
Good
Bad
values = range(10)
allPairs = all([not value % 2 for value in values])
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# [True, False, True, False, True, False, True, False, True, False]
# output: True
All
Comparisons
if x > 10:
result = 'Yes'
else:
result = 'No'
Good
Bad
result = 'Yes' if x > 10 else 'No'
Ternary operator
Lists
mylist = ['yellow', 'red', 'blue', 'green', 'black']
mylist[1:4]
# output: ['red', 'blue', 'green']
mylist[2:]
# output: ['blue', 'green', 'black']
mylist[:2]
# output: ['yellow', 'red']
mylist[-1]
# output: 'black'
mylist[1:-1]
# output: ['red', 'blue', 'green']
Manipulation
Lists
a = [3, 4, 5]
for i in range(len(a)):
a[i] += 3
Good
Bad
a = [3, 4, 5]
a = [i + 3 for i in a]
# Or:
a = map(lambda i: i + 3, a)
List comprehensions
Lists
a = [3, 4, 5]
b = []
for i in a:
if i > 4:
b.append(i)
Good
Bad
a = [3, 4, 5]
b = [i for i in a if i > 4]
# Or:
b = filter(lambda x: x > 4, a)
Filter
Lists
a = [3, 4, 5]
i = 0
for item in items:
print i, item
i += 1
Good
Bad
a = [3, 4, 5]
for i, item in enumerate(a):
print i, item
Enumerate
Generators
def firstn(n):
num, nums = 0, []
while num < n:
nums.append(num)
num += 1
return nums
sum_of_first_n = sum(firstn(1000000))
Bad
def firstn(n):
num = 0
while num < n:
yield num
num += 1
sum_of_first_n = sum(firstn(1000000))
Good
Not in memory list
Generators
square = [i*i for i in xrange(1000000)]
List
square = (i*i for i in irange(1000000))
Generator
Generator vs list
Tuples
temp = a
a = b
b = temp
b, a = a, b
Good
Bad
Swap values
Tuples
l =['David', 'Pythonista', '+1-514-555-1234']
name, title, phone = l
# name: 'David'
# title: 'Pythonista'
# phone: '+1-514-555-1234'
Unpacking
Tuples
List of tuples
names = ['John', 'Eric', 'Terry']
surnames = ['Cleese', 'Idle', 'Gilliam']
people = []
for i in range(len(names)):
people.append((names[i], surnames[i]))
print(people)
# output: [('John', 'Cleese'), ('Eric', 'Idle'), ('Terry', 'Gilliam')]
names = ['John', 'Eric', 'Terry']
surnames = ['Cleese', 'Idle', 'Gilliam']
zip(names, surnames)
# output: [('John', 'Cleese'), ('Eric', 'Idle'), ('Terry', 'Gilliam')]
Good
Bad
Dictionaries
Good
Bad
if d.has_key(key):
print(d[key])
if key in d:
print(d[key])
Dictionaries
Good
Bad
for key in d.keys():
print key
for key in d:
print key
Except
for key in d.keys():
d[str(key)] = d[key]
Dictionaries
navs = {}
for (portfolio, equity, position) in data:
if portfolio not in navs:
navs[portfolio] = 0
navs[portfolio] += position * prices[equity]
Good
Bad
for (portfolio, equity, position) in data:
navs[portfolio] = (navs.get(portfolio, 0)
+ position * prices[equity])
navs = {}
for (portfolio, equity, position) in data:
if portfolio not in navs:
navs[portfolio] = 0
navs[portfolio] += position * prices[equity]
for (portfolio, equity, position) in data:
navs.setdefault(portfolio, 0)
navs[portfolio] += position * prices[equity]
Dictionaries
Good
Bad
navs = {}
for (portfolio, equity, position) in data:
if portfolio not in navs:
navs[portfolio] = 0
navs[portfolio] += position * prices[equity]
navs = defaultdict(int)
for (portfolio, equity, position) in data:
navs[portfolio] += position * prices[equity]
Dictionaries
Good
Bad
given = ['John', 'Eric', 'Terry', 'Michael']
family = ['Cleese', 'Idle', 'Gilliam', 'Palin']
pythons = {}
for i in range(len(given)):
pythons[given[i]] = family[i]
given = ['John', 'Eric', 'Terry', 'Michael']
family = ['Cleese', 'Idle', 'Gilliam', 'Palin']
pythons = dict(zip(given, family))
Dictionaries
Good
Bad
values = range(4)
res = {}
for numb in values:
res[numb] = chr(65 + numb)
res = {i : chr(65+i) for i in range(4)}
Dictionaries
Good
Bad
{0 : 'A', 1 : 'B', 2 : 'C', 3 : 'D'}
What!?!?!
Interactive "_"
>>> 1 + 1
2
>>> _
2
>>> import math
>>> math.pi / 3
1.0471975511965976
>>> angle = _
>>> math.cos(angle)
0.50000000000000011
>>> _
0.50000000000000011
filename = 'foobar.txt'
basename, _, ext = filename.rpartition('.')
Variable "_"
from __future__
>>> from __future__ import braces
File "<stdin>", line 1
SyntaxError: not a chance
from __future__ import division
print 8/7 # prints 1.1428571428571428
print 8//7 # prints 1
Beautiful Python
By aliciapj
Beautiful Python
- 1,394