.. _learning_python_2: ============================= Learning Python Episode Two ============================= .. seealso:: First episode :ref:`learning_python`! String Formatting -------------------------- .. code:: python '{0:,d}'.format(999999999999999999) .. parsed-literal:: '999,999,999,999,999,999' .. code:: python '{:,.2f}'.format(25234234.1231) .. parsed-literal:: '25,234,234.12' .. code:: python '{0:b}'.format((2 ** 16) - 1) .. parsed-literal:: '1111111111111111' .. code:: python #'%b' % ((2 ** 16) - 1) # binary conversion only for method call :: --------------------------------------------------------------------------- ValueError Traceback (most recent call last) in () ----> 1 '%b' % ((2 ** 16) - 1) # binary conversion only for method call ValueError: unsupported format character 'b' (0x62) at index 1 .. code:: python bin((2 ** 16) - 1) .. parsed-literal:: '0b1111111111111111' .. code:: python '%s' % bin((2 ** 16) - 1) .. parsed-literal:: '0b1111111111111111' .. code:: python '{}'.format(bin((2 ** 16) - 1)) .. parsed-literal:: '0b1111111111111111' .. code:: python '%s' % bin((2 ** 16) - 1)[2:] # slice to remove '0b' .. parsed-literal:: '1111111111111111' The formatting method call support `key` and `attribute` references directly .. code:: python '{name} {job} {name}'.format(name='Ema', job='Dev') .. parsed-literal:: 'Ema Dev Ema' .. code:: python '%(name)s %(job)s %(name)s' % dict(name='Ema', job='Dev') .. parsed-literal:: 'Ema Dev Ema' .. code:: python D = dict(name='Ema', job='Dev') '{0[name]} {0[job]} {0[name]}'.format(D) .. parsed-literal:: 'Ema Dev Ema' .. code:: python '{name} {job} {name}'.format(**D) .. parsed-literal:: 'Ema Dev Ema' .. code:: python '%(name)s %(job)s %(name)s' % D .. parsed-literal:: 'Ema Dev Ema' .. code:: python '{0:f}, {1:.2f}, {2:05.2f}'.format(3.14159, 3.14159, 3.14159) .. parsed-literal:: '3.141590, 3.14, 03.14' .. code:: python '{:f}, {:.2f}, {:05.2f}'.format(3.14159, 3.14159, 3.14159) .. parsed-literal:: '3.141590, 3.14, 03.14' .. code:: python # the formatting expression is more concise '%f, %.2f, %05.2f' % (3.14159, 3.14159, 3.14159) .. parsed-literal:: '3.141590, 3.14, 03.14' .. code:: python '{0:.2f}'.format(1.23456) .. parsed-literal:: '1.23' .. code:: python '{0:.2f} {1}'.format(1.23456, 99) .. parsed-literal:: '1.23 99' .. code:: python def myformat(fmt, args): return fmt % args myformat('%s %s', (88, 99)) # custom function .. parsed-literal:: '88 99' .. code:: python str.format('{} {}', 88, 99) # built-in function .. parsed-literal:: '88 99' .. code:: python [1, 4, 6][2:] # slicing a list .. parsed-literal:: [6] .. code:: python ord('C') # str to ASCII code .. parsed-literal:: 67 .. code:: python chr(67) # ASCII code to str .. parsed-literal:: 'C' .. code:: python s = 'a\nb\x1f\000d' str(s) .. parsed-literal:: 'a\nb\x1f\x00d' .. code:: python len(s) .. parsed-literal:: 6 .. code:: python ord('\0') .. parsed-literal:: 0 .. code:: python print(s) .. parsed-literal:: a bd Lists and Dictionaries ---------------------------- .. code:: python help(list) .. parsed-literal:: 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 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__ = | T.__new__(S, ...) -> a new object with type S, a subtype of T Basic List Operations +++++++++++++++++++++++++ .. code:: python len([1, 2, 3]) .. parsed-literal:: 3 .. code:: python [1, 2, 3] + [4, 5, 6] .. parsed-literal:: [1, 2, 3, 4, 5, 6] .. code:: python ['Ni!'] * 4 .. parsed-literal:: ['Ni!', 'Ni!', 'Ni!', 'Ni!'] .. code:: python str([1, 2]) + '34' .. parsed-literal:: '[1, 2]34' .. code:: python [1, 2] + list('34') .. parsed-literal:: [1, 2, '3', '4'] .. code:: python 3 in [1, 3, 4] .. parsed-literal:: True .. code:: python for x in [1, 2, 3]: print(x) .. parsed-literal:: 1 2 3 .. code:: python res = [c * 4 for c in 'spam'] # list comprehensions res .. parsed-literal:: ['ssss', 'pppp', 'aaaa', 'mmmm'] .. code:: python res = [] for c in 'spam': # list comprehension equivalent res.append(c * 4) res .. parsed-literal:: ['ssss', 'pppp', 'aaaa', 'mmmm'] .. code:: python list(map(abs, [-1, -2, 0, 1, 2])) .. parsed-literal:: [1, 2, 0, 1, 2] .. code:: python L = ['spam', 'ciao', 'SMAP!'] L[2] .. parsed-literal:: 'SMAP!' .. code:: python L[1:] .. parsed-literal:: ['ciao', 'SMAP!'] .. code:: python matrix = [[1,2,3], [4,5,6], [7,8,9]] matrix[1][2] .. parsed-literal:: 6 .. code:: python L[1] = 'eggs' L .. parsed-literal:: ['spam', 'eggs', 'SMAP!'] .. code:: python L[0:2] = ['eat', 'more'] L .. parsed-literal:: ['eat', 'more', 'SMAP!'] .. code:: python L = [1,2,3] L[1:2] = [4,5] L .. parsed-literal:: [1, 4, 5, 3] .. code:: python L[1:1] = [6, 7]; L .. parsed-literal:: [1, 6, 7, 4, 5, 3] .. code:: python L[1:2] = []; L .. parsed-literal:: [1, 7, 4, 5, 3] .. code:: python # 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 .. parsed-literal:: [2, 3, 4, 1] .. code:: python L[len(L):] = [5, 6, 7] # empty slice at end append at the end L .. parsed-literal:: [2, 3, 4, 1, 5, 6, 7] .. code:: python L.extend([8, 9, 10]) L .. parsed-literal:: [2, 3, 4, 1, 5, 6, 7, 8, 9, 10] .. code:: python L = ['eat', 'more', 'llll'] L.append('please') L .. parsed-literal:: ['eat', 'more', 'llll', 'please'] .. code:: python L.sort(); L .. parsed-literal:: ['eat', 'llll', 'more', 'please'] .. code:: python L.insert(0, 'first!') L .. parsed-literal:: ['first!', 'eat', 'llll', 'more', 'please'] .. code:: python L.insert(len(L), 'last!') L .. parsed-literal:: ['first!', 'eat', 'llll', 'more', 'please', 'last!'] Sorting lists ++++++++++++++++++++ .. code:: python L = ['abc', 'ABD', 'aBe'] L.sort(); L .. parsed-literal:: ['ABD', 'aBe', 'abc'] .. code:: python L = ['abc', 'ABD', 'aBe'] L.sort(key=str.lower); L .. parsed-literal:: ['abc', 'ABD', 'aBe'] .. code:: python L = ['abc', 'ABD', 'aBe'] L.sort(key=str.lower, reverse=True); L # change sort order .. parsed-literal:: ['aBe', 'ABD', 'abc'] .. code:: python # sorting as built-in function L = ['abc', 'ABD', 'aBe'] sorted(L, key=str.lower, reverse=True) .. parsed-literal:: ['aBe', 'ABD', 'abc'] .. code:: python L = ['abc', 'ABD', 'aBe'] sorted([x.lower() for x in L], reverse=True) .. parsed-literal:: ['abe', 'abd', 'abc'] .. code:: python L = [1, 2] L.extend([3,4,5]); L .. parsed-literal:: [1, 2, 3, 4, 5] .. code:: python L.pop() .. parsed-literal:: 5 .. code:: python L .. parsed-literal:: [1, 2, 3, 4] .. code:: python L.reverse(); L .. parsed-literal:: [4, 3, 2, 1] .. code:: python list(reversed(L)) # reversal built-in with a result (iterator) .. parsed-literal:: [1, 2, 3, 4] .. code:: python L = [] L.append(1) # push onto stack L.append(2) L .. parsed-literal:: [1, 2] .. code:: python L.pop() # pop off stack .. parsed-literal:: 2 .. code:: python L .. parsed-literal:: [1] .. code:: python L = ['spam', 'eggs', 'ham'] L.index('eggs') .. parsed-literal:: 1 .. code:: python L.insert(1, 'toast') L .. parsed-literal:: ['spam', 'toast', 'eggs', 'ham'] .. code:: python L.remove('eggs') L .. parsed-literal:: ['spam', 'toast', 'ham'] .. code:: python L.pop(1) .. parsed-literal:: 'toast' .. code:: python L .. parsed-literal:: ['spam', 'ham'] .. code:: python L.count('spam') # number of occurrences .. parsed-literal:: 1 .. code:: python L = ['spam', 'asd', 'eggs', 'ham'] del L[1] L .. parsed-literal:: ['spam', 'eggs', 'ham'] .. code:: python del L[1:] L .. parsed-literal:: ['spam'] .. code:: python L = ['spam', 'asd', 'eggs', 'ham'] L[1:2] = [] L .. parsed-literal:: ['spam', 'eggs', 'ham'] .. code:: python #L.copy() # make an hard copy for Python 3.3 Dictionaries ---------------------------- .. code:: python D = dict([('name', 'Ema'), ('age', '22')]) D .. parsed-literal:: {'age': '22', 'name': 'Ema'} .. code:: python dict(zip(['age','name'],['33', 'Ema'])) .. parsed-literal:: {'age': '33', 'name': 'Ema'} .. code:: python dict(name='Ema', age='30') .. parsed-literal:: {'age': '30', 'name': 'Ema'} .. code:: python D = dict.fromkeys(['age', 'name']) D .. parsed-literal:: {'age': None, 'name': None} .. code:: python D.popitem() .. parsed-literal:: ('age', None) .. code:: python D = {'name': 'Ema', 'age': '30'} list(D.keys()) .. parsed-literal:: ['age', 'name'] .. code:: python D.keys() .. parsed-literal:: ['age', 'name'] .. code:: python len(D) .. parsed-literal:: 2 .. code:: python 'name' in D .. parsed-literal:: True .. code:: python D = {'eggs': 3, 'spam': 2, 'ham': 1} D['ham'] = ['11','22','33'] D .. parsed-literal:: {'eggs': 3, 'ham': ['11', '22', '33'], 'spam': 2} .. code:: python del D['eggs']; D .. parsed-literal:: {'ham': ['11', '22', '33'], 'spam': 2} .. code:: python D = {'eggs': 3, 'spam': 2, 'ham': 1} D.values() .. parsed-literal:: [3, 1, 2] .. code:: python D.items() .. parsed-literal:: [('eggs', 3), ('ham', 1), ('spam', 2)] .. code:: python D.pop('ham') # pop a dictionary by key .. parsed-literal:: 1 .. code:: python L = ['aa', 'bb', 'cc'] # pop a list by position L.pop(); L .. parsed-literal:: ['aa', 'bb'] .. code:: python D2 = {'toast': 4, 'muffin': 2} D.update(D2) D .. parsed-literal:: {'eggs': 3, 'muffin': 2, 'spam': 2, 'toast': 4} .. code:: python table = {'test1': '111', 'test2': '222', 'test3': '333'} table['test2'] .. parsed-literal:: '222' .. code:: python table.keys() .. parsed-literal:: ['test1', 'test3', 'test2'] .. code:: python list(table.items()) .. parsed-literal:: [('test1', '111'), ('test3', '333'), ('test2', '222')] .. code:: python [title for (title, val) in table.items() if val == '222'] .. parsed-literal:: ['test2'] .. code:: python V = '333' [key for key in table.keys() if table[key] == V] .. parsed-literal:: ['test3'] .. code:: python D = {} D[99] = 'spam' D[99] .. parsed-literal:: 'spam' .. code:: python D .. parsed-literal:: {99: 'spam'} .. code:: python Matrix = {} Matrix[(2, 3, 4)] = 11 Matrix[(5, 7, 8)] = 65 Matrix .. parsed-literal:: {(2, 3, 4): 11, (5, 7, 8): 65} .. code:: python #Matrix[(6, 5, 2)] :: --------------------------------------------------------------------------- KeyError Traceback (most recent call last) in () ----> 1 Matrix[(6, 5, 2)] KeyError: (6, 5, 2) .. code:: python if (2, 3, 4) in Matrix: print(Matrix[(2, 3, 4)]) .. parsed-literal:: 11 .. code:: python # Try Catch and recover try: print(Matrix[(2, 7, 4)]) except KeyError: print(0) .. parsed-literal:: 0 .. code:: python Matrix.get((2, 7, 2), 'None') # retrieve with default value if doesn't exist .. parsed-literal:: 'None' Ways to Make Dictionaries +++++++++++++++++++++++++++++++++ .. code:: python # 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)]) .. parsed-literal:: {'age': 40, 'name': 'Bob'} .. code:: python # dict with zipped key/value tuples dict(zip(['name', 'age'], ['Ema', 40])) .. parsed-literal:: {'age': 40, 'name': 'Ema'} .. code:: python dict.fromkeys(['a', 'b'], 0) .. parsed-literal:: {'a': 0, 'b': 0} .. code:: python dict.fromkeys('ab', 0) .. parsed-literal:: {'a': 0, 'b': 0} .. code:: python dict(a=0, b=0) .. parsed-literal:: {'a': 0, 'b': 0} .. code:: python dict([('a', 0), ('b', 0)]) .. parsed-literal:: {'a': 0, 'b': 0} Tuples & Files --------------------------- .. code:: python type(()) .. parsed-literal:: tuple .. code:: python tuple('spam') .. parsed-literal:: ('s', 'p', 'a', 'm') .. code:: python T = 's', 'a'; T .. parsed-literal:: ('s', 'a') .. code:: python len(T) .. parsed-literal:: 2 .. code:: python T * 3 .. parsed-literal:: ('s', 'a', 's', 'a', 's', 'a') .. code:: python for x in T: print(x) .. parsed-literal:: s a .. code:: python (1, 2) + (4, 6) .. parsed-literal:: (1, 2, 4, 6) .. code:: python T = (1, 2, 3, 4) T[0], T[1:3] .. parsed-literal:: (1, (2, 3)) .. code:: python x = (30) x # an integer .. parsed-literal:: 30 .. code:: python x = (30,) x # a tuple containing an integer .. parsed-literal:: (30,) .. code:: python T = ('cc', 'aa', 'dd', 'bb') tmp = list(T) # make a list from a tuple tmp.sort() tmp .. parsed-literal:: ['aa', 'bb', 'cc', 'dd'] .. code:: python T = tuple(tmp) # make a tuple from a list T .. parsed-literal:: ('aa', 'bb', 'cc', 'dd') .. code:: python sorted(T) # same as above but shorter .. parsed-literal:: ['aa', 'bb', 'cc', 'dd'] .. code:: python T = (1, 2, 3, 4) L = [x + 20 for x in T] L .. parsed-literal:: [21, 22, 23, 24] .. code:: python T = (1, 2, 3, 4, 5, 2) T.index(2) .. parsed-literal:: 1 .. code:: python T.count(2) .. parsed-literal:: 2 .. code:: python T.index(2, 2) .. parsed-literal:: 5 .. code:: python bob = ('bob', 40.5, ['aaa', 'bbb']) bob .. parsed-literal:: ('bob', 40.5, ['aaa', 'bbb']) .. code:: python bob[0], bob[2] .. parsed-literal:: ('bob', ['aaa', 'bbb']) .. code:: python bob = dict(name='Bob', age=40.5, jobs=['aaa', 'bbb']) bob .. parsed-literal:: {'age': 40.5, 'jobs': ['aaa', 'bbb'], 'name': 'Bob'} .. code:: python bob['name'], bob['jobs'] .. parsed-literal:: ('Bob', ['aaa', 'bbb']) .. code:: python tuple(bob.values()) .. parsed-literal:: (40.5, ['aaa', 'bbb'], 'Bob') .. code:: python list(bob.items()) .. parsed-literal:: [('age', 40.5), ('jobs', ['aaa', 'bbb']), ('name', 'Bob')] Named Tuples ++++++++++++++++++++++ .. code:: python from collections import namedtuple Rec = namedtuple('Rec', ['name', 'age', 'jobs']) .. code:: python bob = Rec('Bob', age=40.5, jobs=['aaa', 'bbb']) bob .. parsed-literal:: Rec(name='Bob', age=40.5, jobs=['aaa', 'bbb']) .. code:: python bob[0], bob[2] .. parsed-literal:: ('Bob', ['aaa', 'bbb']) .. code:: python bob.name, bob.jobs .. parsed-literal:: ('Bob', ['aaa', 'bbb']) .. code:: python O = bob._asdict() O .. parsed-literal:: OrderedDict([('name', 'Bob'), ('age', 40.5), ('jobs', ['aaa', 'bbb'])])