Learning Python Episode Two

See also

First episode Learning Python Episode One!

String Formatting

'{0:,d}'.format(999999999999999999)
'999,999,999,999,999,999'
'{:,.2f}'.format(25234234.1231)
'25,234,234.12'
'{0:b}'.format((2 ** 16) - 1)
'1111111111111111'
#'%b' % ((2 ** 16) - 1) # binary conversion only for method call
---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

<ipython-input-34-4cf5c090a437> in <module>()
----> 1 '%b' % ((2 ** 16) - 1) # binary conversion only for method call


ValueError: unsupported format character 'b' (0x62) at index 1
bin((2 ** 16) - 1)
'0b1111111111111111'
'%s' % bin((2 ** 16) - 1)
'0b1111111111111111'
'{}'.format(bin((2 ** 16) - 1))
'0b1111111111111111'
'%s' % bin((2 ** 16) - 1)[2:] # slice to remove '0b'
'1111111111111111'

The formatting method call support key and attribute references directly

'{name} {job} {name}'.format(name='Ema', job='Dev')
'Ema Dev Ema'
'%(name)s %(job)s %(name)s' % dict(name='Ema', job='Dev')
'Ema Dev Ema'
D = dict(name='Ema', job='Dev')
'{0[name]} {0[job]} {0[name]}'.format(D)
'Ema Dev Ema'
'{name} {job} {name}'.format(**D)
'Ema Dev Ema'
'%(name)s %(job)s %(name)s' % D
'Ema Dev Ema'
'{0:f}, {1:.2f}, {2:05.2f}'.format(3.14159, 3.14159, 3.14159)
'3.141590, 3.14, 03.14'
'{:f}, {:.2f}, {:05.2f}'.format(3.14159, 3.14159, 3.14159)
'3.141590, 3.14, 03.14'
# the formatting expression is more concise
'%f, %.2f, %05.2f' % (3.14159, 3.14159, 3.14159)
'3.141590, 3.14, 03.14'
'{0:.2f}'.format(1.23456)
'1.23'
'{0:.2f} {1}'.format(1.23456, 99)
'1.23 99'
def myformat(fmt, args): return fmt % args
myformat('%s %s', (88, 99)) # custom function
'88 99'
str.format('{} {}', 88, 99) # built-in function
'88 99'
[1, 4, 6][2:] # slicing a list
[6]
ord('C') # str to ASCII code
67
chr(67) # ASCII code to str
'C'
s = 'a\nb\x1f\000d'
str(s)
'anbx1fx00d'
len(s)
6
ord('\0')
0
print(s)
a
bd

Lists and Dictionaries

help(list)
Help on class list in module __builtin__:

class list(object)
 |  list() -> new empty list
 |  list(iterable) -> new list initialized from iterable's items
 |
 |  Methods defined here:
 |
 |  __add__(...)
 |      x.__add__(y) <==> x+y
 |
 |  __contains__(...)
 |      x.__contains__(y) <==> y in x
 |
 |  __delitem__(...)
 |      x.__delitem__(y) <==> del x[y]
 |
 |  __delslice__(...)
 |      x.__delslice__(i, j) <==> del x[i:j]
 |
 |      Use of negative indices is not supported.
 |
 |  __eq__(...)
 |      x.__eq__(y) <==> x==y
 |
 |  __ge__(...)
 |      x.__ge__(y) <==> x>=y
 |
 |  __getattribute__(...)
 |      x.__getattribute__('name') <==> x.name
 |
 |  __getitem__(...)
 |      x.__getitem__(y) <==> x[y]
 |
 |  __getslice__(...)
 |      x.__getslice__(i, j) <==> x[i:j]
 |
 |      Use of negative indices is not supported.
 |
 |  __gt__(...)
 |      x.__gt__(y) <==> x>y
 |
 |  __iadd__(...)
 |      x.__iadd__(y) <==> x+=y
 |
 |  __imul__(...)
 |      x.__imul__(y) <==> x*=y
 |
 |  __init__(...)
 |      x.__init__(...) initializes x; see help(type(x)) for signature
 |
 |  __iter__(...)
 |      x.__iter__() <==> iter(x)
 |
 |  __le__(...)
 |      x.__le__(y) <==> x<=y
 |
 |  __len__(...)
 |      x.__len__() <==> len(x)
 |
 |  __lt__(...)
 |      x.__lt__(y) <==> x<y
 |
 |  __mul__(...)
 |      x.__mul__(n) <==> x*n
 |
 |  __ne__(...)
 |      x.__ne__(y) <==> x!=y
 |
 |  __repr__(...)
 |      x.__repr__() <==> repr(x)
 |
 |  __reversed__(...)
 |      L.__reversed__() -- return a reverse iterator over the list
 |
 |  __rmul__(...)
 |      x.__rmul__(n) <==> n*x
 |
 |  __setitem__(...)
 |      x.__setitem__(i, y) <==> x[i]=y
 |
 |  __setslice__(...)
 |      x.__setslice__(i, j, y) <==> x[i:j]=y
 |
 |      Use  of negative indices is not supported.
 |
 |  __sizeof__(...)
 |      L.__sizeof__() -- size of L in memory, in bytes
 |
 |  append(...)
 |      L.append(object) -- append object to end
 |
 |  count(...)
 |      L.count(value) -> integer -- return number of occurrences of value
 |
 |  extend(...)
 |      L.extend(iterable) -- extend list by appending elements from the iterable
 |
 |  index(...)
 |      L.index(value, [start, [stop]]) -> integer -- return first index of value.
 |      Raises ValueError if the value is not present.
 |
 |  insert(...)
 |      L.insert(index, object) -- insert object before index
 |
 |  pop(...)
 |      L.pop([index]) -> item -- remove and return item at index (default last).
 |      Raises IndexError if list is empty or index is out of range.
 |
 |  remove(...)
 |      L.remove(value) -- remove first occurrence of value.
 |      Raises ValueError if the value is not present.
 |
 |  reverse(...)
 |      L.reverse() -- reverse IN PLACE
 |
 |  sort(...)
 |      L.sort(cmp=None, key=None, reverse=False) -- stable sort IN PLACE;
 |      cmp(x, y) -> -1, 0, 1
 |
 |  ----------------------------------------------------------------------
 |  Data and other attributes defined here:
 |
 |  __hash__ = None
 |
 |  __new__ = <built-in method __new__ of type object>
 |      T.__new__(S, ...) -> a new object with type S, a subtype of T

Basic List Operations

len([1, 2, 3])
3
[1, 2, 3] + [4, 5, 6]
[1, 2, 3, 4, 5, 6]
['Ni!'] * 4
['Ni!', 'Ni!', 'Ni!', 'Ni!']
str([1, 2]) + '34'
'[1, 2]34'
[1, 2] + list('34')
[1, 2, '3', '4']
3 in [1, 3, 4]
True
for x in [1, 2, 3]:
    print(x)
1
2
3
res = [c * 4 for c in 'spam'] # list comprehensions
res
['ssss', 'pppp', 'aaaa', 'mmmm']
res = []
for c in 'spam': # list comprehension equivalent
    res.append(c * 4)
res
['ssss', 'pppp', 'aaaa', 'mmmm']
list(map(abs, [-1, -2, 0, 1, 2]))
[1, 2, 0, 1, 2]
L = ['spam', 'ciao', 'SMAP!']
L[2]
'SMAP!'
L[1:]
['ciao', 'SMAP!']
matrix = [[1,2,3], [4,5,6], [7,8,9]]
matrix[1][2]
6
L[1] = 'eggs'
L
['spam', 'eggs', 'SMAP!']
L[0:2] = ['eat', 'more']
L
['eat', 'more', 'SMAP!']
L = [1,2,3]
L[1:2] = [4,5]
L
[1, 4, 5, 3]
L[1:1] = [6, 7]; L
[1, 6, 7, 4, 5, 3]
L[1:2] = []; L
[1, 7, 4, 5, 3]
# can be used to concatenate at the front of the list
L = [1]
L[:0] = [2, 3, 4] # empty slice at the start append at the front
L
[2, 3, 4, 1]
L[len(L):] = [5, 6, 7] # empty slice at end append at the end
L
[2, 3, 4, 1, 5, 6, 7]
L.extend([8, 9, 10])
L
[2, 3, 4, 1, 5, 6, 7, 8, 9, 10]
L = ['eat', 'more', 'llll']
L.append('please')
L
['eat', 'more', 'llll', 'please']
L.sort(); L
['eat', 'llll', 'more', 'please']
L.insert(0, 'first!')
L
['first!', 'eat', 'llll', 'more', 'please']
L.insert(len(L), 'last!')
L
['first!', 'eat', 'llll', 'more', 'please', 'last!']

Sorting lists

L = ['abc', 'ABD', 'aBe']
L.sort(); L
['ABD', 'aBe', 'abc']
L = ['abc', 'ABD', 'aBe']
L.sort(key=str.lower); L
['abc', 'ABD', 'aBe']
L = ['abc', 'ABD', 'aBe']
L.sort(key=str.lower, reverse=True); L # change sort order
['aBe', 'ABD', 'abc']
# sorting as built-in function
L = ['abc', 'ABD', 'aBe']
sorted(L, key=str.lower, reverse=True)
['aBe', 'ABD', 'abc']
L = ['abc', 'ABD', 'aBe']
sorted([x.lower() for x in L], reverse=True)
['abe', 'abd', 'abc']
L = [1, 2]
L.extend([3,4,5]); L
[1, 2, 3, 4, 5]
L.pop()
5
L
[1, 2, 3, 4]
L.reverse(); L
[4, 3, 2, 1]
list(reversed(L)) # reversal built-in with a result (iterator)
[1, 2, 3, 4]
L = []
L.append(1) # push onto stack
L.append(2)
L
[1, 2]
L.pop() # pop off stack
2
L
[1]
L = ['spam', 'eggs', 'ham']
L.index('eggs')
1
L.insert(1, 'toast')
L
['spam', 'toast', 'eggs', 'ham']
L.remove('eggs')
L
['spam', 'toast', 'ham']
L.pop(1)
'toast'
L
['spam', 'ham']
L.count('spam') # number of occurrences
1
L = ['spam', 'asd', 'eggs', 'ham']
del L[1]
L
['spam', 'eggs', 'ham']
del L[1:]
L
['spam']
L = ['spam', 'asd', 'eggs', 'ham']
L[1:2] = []
L
['spam', 'eggs', 'ham']
#L.copy() # make an hard copy for Python 3.3

Dictionaries

D = dict([('name', 'Ema'), ('age', '22')])
D
{'age': '22', 'name': 'Ema'}
dict(zip(['age','name'],['33', 'Ema']))
{'age': '33', 'name': 'Ema'}
dict(name='Ema', age='30')
{'age': '30', 'name': 'Ema'}
D = dict.fromkeys(['age', 'name'])
D
{'age': None, 'name': None}
D.popitem()
('age', None)
D = {'name': 'Ema', 'age': '30'}
list(D.keys())
['age', 'name']
D.keys()
['age', 'name']
len(D)
2
'name' in D
True
D = {'eggs': 3, 'spam': 2, 'ham': 1}
D['ham'] = ['11','22','33']
D
{'eggs': 3, 'ham': ['11', '22', '33'], 'spam': 2}
del D['eggs']; D
{'ham': ['11', '22', '33'], 'spam': 2}
D = {'eggs': 3, 'spam': 2, 'ham': 1}
D.values()
[3, 1, 2]
D.items()
[('eggs', 3), ('ham', 1), ('spam', 2)]
D.pop('ham') # pop a dictionary by key
1
L = ['aa', 'bb', 'cc'] # pop a list by position
L.pop(); L
['aa', 'bb']
D2 = {'toast': 4, 'muffin': 2}
D.update(D2)
D
{'eggs': 3, 'muffin': 2, 'spam': 2, 'toast': 4}
table = {'test1': '111',
         'test2': '222',
         'test3': '333'}
table['test2']
'222'
table.keys()
['test1', 'test3', 'test2']
list(table.items())
[('test1', '111'), ('test3', '333'), ('test2', '222')]
[title for (title, val) in table.items() if val == '222']
['test2']
V = '333'
[key for key in table.keys() if table[key] == V]
['test3']
D = {}
D[99] = 'spam'
D[99]
'spam'
D
{99: 'spam'}
Matrix = {}
Matrix[(2, 3, 4)] = 11
Matrix[(5, 7, 8)] = 65
Matrix
{(2, 3, 4): 11, (5, 7, 8): 65}
#Matrix[(6, 5, 2)]
---------------------------------------------------------------------------

KeyError                                  Traceback (most recent call last)

<ipython-input-121-863821a16dc2> in <module>()
----> 1 Matrix[(6, 5, 2)]


KeyError: (6, 5, 2)
if (2, 3, 4) in Matrix:
    print(Matrix[(2, 3, 4)])
11
# Try Catch and recover
try:
    print(Matrix[(2, 7, 4)])
except KeyError:
    print(0)
0
Matrix.get((2, 7, 2), 'None') # retrieve with default value if doesn't exist
'None'

Ways to Make Dictionaries

# literal exp
{'name': 'Bob', 'age': 40}

# assign keys dynamic
D = {}
D['name'] = 'Bob'
D['age'] = 40

# dict keyword argument form
dict(name='Bob', age=40)

# dict key/valy tuples form
dict([('name', 'Bob'), ('age', 40)])
{'age': 40, 'name': 'Bob'}
# dict with zipped key/value tuples
dict(zip(['name', 'age'], ['Ema', 40]))
{'age': 40, 'name': 'Ema'}
dict.fromkeys(['a', 'b'], 0)
{'a': 0, 'b': 0}
dict.fromkeys('ab', 0)
{'a': 0, 'b': 0}
dict(a=0, b=0)
{'a': 0, 'b': 0}
dict([('a', 0), ('b', 0)])
{'a': 0, 'b': 0}

Tuples & Files

type(())
tuple
tuple('spam')
('s', 'p', 'a', 'm')
T = 's', 'a'; T
('s', 'a')
len(T)
2
T * 3
('s', 'a', 's', 'a', 's', 'a')
for x in T: print(x)
s
a
(1, 2) + (4, 6)
(1, 2, 4, 6)
T = (1, 2, 3, 4)
T[0], T[1:3]
(1, (2, 3))
x = (30)
x # an integer
30
x = (30,)
x # a tuple containing an integer
(30,)
T = ('cc', 'aa', 'dd', 'bb')
tmp = list(T) # make a list from a tuple
tmp.sort()
tmp
['aa', 'bb', 'cc', 'dd']
T = tuple(tmp) # make a tuple from a list
T
('aa', 'bb', 'cc', 'dd')
sorted(T) # same as above but shorter
['aa', 'bb', 'cc', 'dd']
T = (1, 2, 3, 4)
L = [x + 20 for x in T]
L
[21, 22, 23, 24]
T = (1, 2, 3, 4, 5, 2)
T.index(2)
1
T.count(2)
2
T.index(2, 2)
5
bob = ('bob', 40.5, ['aaa', 'bbb'])
bob
('bob', 40.5, ['aaa', 'bbb'])
bob[0], bob[2]
('bob', ['aaa', 'bbb'])
bob = dict(name='Bob', age=40.5, jobs=['aaa', 'bbb'])
bob
{'age': 40.5, 'jobs': ['aaa', 'bbb'], 'name': 'Bob'}
bob['name'], bob['jobs']
('Bob', ['aaa', 'bbb'])
tuple(bob.values())
(40.5, ['aaa', 'bbb'], 'Bob')
list(bob.items())
[('age', 40.5), ('jobs', ['aaa', 'bbb']), ('name', 'Bob')]

Named Tuples

from collections import namedtuple
Rec = namedtuple('Rec', ['name', 'age', 'jobs'])
bob = Rec('Bob', age=40.5, jobs=['aaa', 'bbb'])
bob
Rec(name='Bob', age=40.5, jobs=['aaa', 'bbb'])
bob[0], bob[2]
('Bob', ['aaa', 'bbb'])
bob.name, bob.jobs
('Bob', ['aaa', 'bbb'])
O = bob._asdict()
O
OrderedDict([('name', 'Bob'), ('age', 40.5), ('jobs', ['aaa', 'bbb'])])