// * Python 2

List repetition with nested lists

In [1]:
my_list = [[0]*5]*4
for i in range(3):
    my_list[2][i] = 1
In [2]:
print my_list
[[1, 1, 1, 0, 0], [1, 1, 1, 0, 0], [1, 1, 1, 0, 0], [1, 1, 1, 0, 0]]
In [3]:
new_list = [[0]*5 for x in range(4)]
In [4]:
for i in range(3):
    new_list[2][i] = 1
new_list
Out[4]:
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [1, 1, 1, 0, 0], [0, 0, 0, 0, 0]]

Don't mix spaces and tabs

Just don't. You would cry.

where, Tab(→) = 4 spaces

→  Some code here(firstArgument,
→   →   →   →  ···secondOne,
→   →   →  ·······modified);

where, Tab(→)= 2 spaces

→ Some code here(firstArgument,
→ → → → ···secondOne,
→ → → ·······modified);

Explicit type cast of strings

In [ ]:
float('i-am-a-string')
In [ ]:
float('inf')
In [ ]:
float('inf') > 6

Same hash in a dict

In [ ]:
a={}
a[1.0]= 'quora'
a[True] = 'twitter'
a[1]= 'facebook'
In [ ]:
print a[True]
In [ ]:
hash(1) == hash(1.0)

Integers in Python

In [ ]:
a = 25
b = 25
In [ ]:
print id(a)
print id(b)
In [ ]:
a = 300
b = 300
In [ ]:
print id(a)
print id(b)
In [ ]:
 

Local Variable Optimization

This flaw bites people fairly often. Consider the following function; what do you think happens when you run it?:

In [ ]:
i=1
def f():
    #global i
    print "i=",i
    i = i + 1 

f()

Trailing spaces

In [ ]:
for i in range(10): print "*",
In [ ]:
import sys
for i in range(10): sys.stdout.write("*")

Catching Multiple Exceptions

In [ ]:
try:
    #something that raises an error...
except IndexError, ValueError:
    # expects to catch IndexError and ValueError
    # wrong!
In [ ]:
# correct
try:
    1/0
except (ZeroDivisionError, IndexError, ValueError), e:
    print e
    # integer division or modulo by zero

The += operator

x += 42

x = x + 42
a = 1
a = a + 42
# a is 43
a = 1
a += 42
# a is 43
In [ ]:
z = [1, 2, 3]
In [ ]:
z += [4]
id(z)
In [ ]:
z = z + [5]
id(z)

Class attributes vs instance attributes

>>> class Foo:
...     a = 42
...     def __init__(self):
...         self.a = 43
...     
>>> f = Foo()
>>> f.a
43
>>> class Foo:
...     a = 42
...     
>>> f = Foo()
>>> f.a
42
In [5]:
class Foo:
    bar = []
    def __init__(self, x):
        self.bar += [x]
#         self.bar = self.bar + [x]
In [6]:
f = Foo(42)
In [7]:
f.bar
Out[7]:
[42]
In [8]:
g = Foo(100)
In [9]:
g.bar
Out[9]:
[42, 100]

List slicing

>>> x = [10, 20, 30, 40, 50]
In [11]:
x = [10, 20, 30, 40, 50]
In [12]:
x[6:]
Out[12]:
[]

Mutable default arguments

>>> def myfunc(x=[]):
...     x.append(222)
...     print x

>>> myfunc([1, 2, 3])
[1, 2, 3, 222]

>>> x = [1, 2]

>>> myfunc(x)
[1, 2, 222]

>>> x
[1, 2, 222]

This was expected. But now ..

>>> myfunc()
[222]

>>> myfunc()
[222, 222]

>>> myfunc()
[222, 222, 222]

String concatenation

To illustrate this, a simple benchmark. (timeit is a simple function that runs another function and returns how long it took to complete, in seconds.)

>>> def f():
...     s = ""
...     for i in range(100000):
...         s = s + "abcdefg"[i % 7]
...     
>>> timeit(f)
23.7819999456

>>> def g():
...     z = []
...     for i in range(100000):
...         z.append("abcdefg"[i % 7])
...     return ''.join(z)
...     
>>> timeit(g)
0.343000054359

QUICK QUESTION

>>> t = (1,2,[1,2,3],)
>>> t[2] += [4, 5]
In [ ]:
t = (1,2,[1,2,3],)
t[2] += [4,5]
In [ ]:
t

[Tip] Ask for forgiveness than permission

Don't :

if os.path.isfile(file_path) :
    file = open(file_path)
else :
    # do something

Do :

try :
    file =  open(file_path)
except OSError as e:
    # do something

QUESTIONS ? O.o

Twitter: @onlyrealmvp