Code like a Pythonista is a popular style guide for Python programming. In this post I will list down the main points of the guide

  • Whitespace1
    • 4 spaces per indentation level
    • No hard tabs
    • Never mix tabs and spaces
    • One blank line between functions
    • Two blank lines between classes
  • Whitespace2
    • Add a space after “,” in dicts, tuples, & argument lists, and after “:” in dicts, but not before
    • Put spaces around assignments & comparisons
    • No spaces just inside parentheses or just before argument lists
    • No spaces just inside docstrings.

def make_squares(key, value=0) : “““Return a dictionary and a list…””” d = {key: value} l = [keyey, value] return d, l

  • Naming * joined_lower for functions, methods and attributes * joined_lower or ALL_CAPS for constants * StudlyCaps for classes * Attributes : interface, _internal, __private * Avoid __private
  • Long lines and Continuations : Keep lines below 80 characters in length
  • Use Docstrings and Comments to explain how to use the code
  • Comma is a tuple constructor , not the parentheses
  • In an interactive interpreter, whenever you evaluate an expression or call a function,the result is bound to a temporary name, _ underscore.By typing underscore, one can print the last expression
  • use ‘key in dict’ and not dict.has_key()
  • Try to use to set and get default methods in the dictionary and cut unnecessary code
  • defaultdict is new in Python 2.5 and you can make your code even more efficient

from collections import defaultdict data = [(‘python’,1), (‘R’,2),(‘python’,3),(‘Ruby’,4)] x = defaultdict(list) for (a, b) in data: x[a].append(b)

print data print x

[(‘python’, 1), (‘R’, 2), (‘python’, 3), (‘Ruby’, 4)] defaultdict(, {‘python’: [1, 3], ‘R’: [2], ‘Ruby’: [4]})

  • Its elegant to take advantage of intrinsic truth values
  • enumerate takes a list and returns (index,item) pairs
  • enumerate function returns an iterator
  • Other languages have ‘variable’ whereas Python has ‘names’. Although we commonly refer to ‘variables’ in Python , we really mean names or ‘identifiers’
  • Be careful with default parameter values in functions
  • The namespace of an object’s instance attributes is jus a dictionary, self.__dict__
  • List comprehensions (‘listcomps’) are syntax shortcuts

import math data = [i for i in range(8)] x =[] for item in data: if item > 3 : x.append(round(math.sqrt(item), 3)) print x #Using listcomps print [round(math.sqrt(item), 3) for item in data if item > 3]

[2.0, 2.236, 2.449, 2.646] [2.0, 2.236, 2.449, 2.646]

  • Generator expressions - function is similar to listcomps . Use a generator expression when the computed list is just an intermediate step
  • Use a list comprehension when a computed list is the desired end result
  • Decorate-Sort-Undecorate pattern

import random x = zip(random.sample(xrange(1,1000), 5) , random.sample(xrange(1,1000), 5),random.sample(xrange(1,1000), 5)) to_sort = [(item[0] , item[1],item) for item in x] to_sort.sort() sorted_list = [item[-1] for item in to_sort] print x print sorted_list

[(579, 499, 281), (388, 52, 121), (88, 541, 215), (731, 234, 47), (288, 794, 109)] [(88, 541, 215), (288, 794, 109), (388, 52, 121), (579, 499, 281), (731, 234, 47)]

  • Python 2.4 introduced an optional argument in sort method that makes the above DSU pattern redundant

import random x = zip(random.sample(xrange(1,1000), 5) , random.sample(xrange(1,1000), 5),random.sample(xrange(1,1000), 5)) print x def my_key(item): return (item[0],item[1]) x.sort(key = my_key) print x

[(94, 439, 973), (798, 938, 353), (280, 908, 391), (983, 806, 668), (694, 776, 776)] [(94, 439, 973), (280, 908, 391), (694, 776, 776), (798, 938, 353), (983, 806, 668)]

  • EAFP Vs LBYL - Easier to Ask For Permission Vs Look Before You Leap. EAFP is preferred but not always. An example that I came across on stackoverflow

#EAFP def safe_divide_2(x, y): try: return x/y except ZeroDivisionError: print “Divide-by-0 attempt detected” return None #LBYL def safe_divide_1(x, y): if y == 0: print “Divide-by-0 attempt detected” return None else: return x/y

  • Don’t use wild card imports
  • Module Structure
    • import
    • constants
    • execution classes
    • interface functions
    • classes
    • internal functions & classes
  • Don’t reinvent the wheel
    • Check Python library
    • Check Python package index