Python Tips, Part 2
A second collection of Python 2 techniques for strings, lists, mutable references, slicing, ellipses, and file operations.
Using join
For combining strings, join is generally recommended. The most frequently used string operations include join, split, and replace, along with partition.
You can pass a generator expression directly to join:
m = map(str, range(9))','.join(x for x in m if x != '3')
# Rather than','.join([x for x in m if x != '3'])Removing multiple equal values from a list
list.remove is not suitable here because it deletes only the first matching value from left to right. Two better approaches are:
m = ['a', 'b', 'c', 'a']m = filter(lambda x: x !='a', m)Or:
m[:] = (x for x in m if x != 'a')Generating a random string of n characters
import randomimport string
rand_str = "".join([random.choice(string.letters+string.digits) for _ in xrange(n)])Reference-type pitfalls
Function arguments
A default argument is evaluated only once, when the function is defined. Multiple calls therefore reuse the same mutable object:
def test(data, x=[]): x.append(data) return xprint test(3)# [3]print test(4)# [3, 4]Default values with dict.fromkeys
This has the same problem as a mutable default argument: the values for multiple keys refer to the same list. Using {} produces the same result.
>>> a = dict.fromkeys('bc', [])>>> a['b'].append(6)>>> a{'b': [6], 'c': [6]}Declaring multiple variables
It is common to need several empty lists or dictionaries. The following incorrect form makes multiple variables share the same [] or {}:
a = b = []c = d = {}Use separate objects instead:
a, b = [], []# for a lot of varc, d, e, f = [{} for _ in xrange(4)]Immutable values such as int, str, and bool do not have this problem, so this is fine:
a = b = TrueYou can also delete multiple items in one del statement:
>>> a = range(3)>>> del a[2], a[0]>>> a[1]Slicing
Use a step of -1 to reverse a list:
>>> a = range(7)>>> a[::-1][6, 5, 4, 3, 2, 1, 0]>>> a[::2][0, 2, 4, 6]Assigning an empty list to a slice removes that range, just like del a[1:4]:
>>> a = [1, 2, 3, 4, 5, 6, 7]>>> a[1:4] = []>>> a[1, 5, 6, 7]Remove items at even indexes:
>>> a = [0, 1, 2, 3, 4, 5, 6, 7]>>> del a[::2]>>> a[1, 3, 5, 7]Ellipsis
Ellipsis is mainly useful with multidimensional arrays, where it reduces the complexity of indexing. I rarely use it; a more detailed explanation can be found elsewhere.
>>> class C(object):... def __getitem__(self, item):... return item...>>> C()[1:2, ..., 3](slice(1, 2, None), Ellipsis, 3)File operations
Reading an entire file
Use binary mode, such as rb. With r, only part of the file may be read.
with open(path, 'rb') as f: return f.read()Reading line by line
Treat the file object as an iterator:
with open(path, 'r') as f: for line in f: print line