Data Structures

list

Ordered collection of items

    >>> dir(list)
    ['__add__', '__class__', '__class_getitem__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']

Most used operations: append, count, extend, index, insert, pop, remove, reverse, sort

    # creation
    >>> my_list = list()
    >>> my_list = []
    >>> my_list = [1, 2, True, 'message']
    >>> my_list
    [1, 2, True, 'message']

    # indices
    >>> my_list.append(3)
    >>> my_list
    [1, 2, True, 'message', 3]
    >>> my_list[0]
    1
    >>> my_list[-1]
    3
    >>> my_list[2:3]
    [True]
    >>> my_list[2:3]
    [True]
    >>> my_list[2:]
    [True, 'message', 3]

    # concatenation
    >>> numbers = [1,2,3]
    >>> letters=['a', 'b', 'c']
    >>> numbers + letters
    [1, 2, 3, 'a', 'b', 'c']
    >>> letters + numbers
    ['a', 'b', 'c', 1, 2, 3]

tuples

Immutable ordered list

    >>> dir(tuple)
    ['__add__', '__class__', '__class_getitem__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'count', 'index']
    # creation
    >>> my_tuple = (1, 2, 3)
    >>> my_tuple
    (1, 2, 3)
    >>> my_tuple[0]
    1
    >>> my_tuple[-1]
    3

    # single element
    >>> one_element_tuple = (1)
    >>> one_element_tuple
    1
    >>> type(one_element_tuple)
    <type 'int'>
    >>> one_element_tuple = (1,)
    >>> one_element_tuple
    (1,)
    >>> one_element_tuple = 1,
    >>> one_element_tuple
    (1,)
    >>> type(one_element_tuple)
    <type 'tuple'>

    # unpacking
    >>> a, b, c = (1, 2, 3)

    # must have the same number of elements:
    #   few values on the left
    >>> a, b, c = (1, 2)
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    ValueError: need more than 2 values to unpack

    # must have the same number of elements:
    #   too many values on the left
    >>> a, b, c = (1, 2, 3, 4)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module> ValueError: too many values to unpack

    # ignoring single values assigning to '_'
    >>> a, b, c, _ = (1, 2, 3, 4)
    >>> a, _, c = (1, 2, 3)

    # ignoring a number of values with '*'
    >>> a, b, c, *d = (1, 2, 3, 4, 5, 6, 7, 8, 9)
    >>> d
    [4, 5, 6, 7, 8, 9]
    # can be used to ignore a number of values in the middle
    >>> a, b, *c, d = (1, 2, 3, 4, 5, 6, 7, 8, 9)
    >>> c
    [3, 4, 5, 6, 7, 8,]
    >>> d
    9

Differences between tuple and list:

    >>> print(dir(list))
    [..., 'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
    >>> print(dir(tuple))
    [..., 'count', 'index']
    >>> a_list = [1,2,3]
    >>> a_tuple=(1,2,3)
    >>> sys.getsizeof(a_list)
    88
    >>> sys.getsizeof(a_tuple)
    72

Notice the different sizes.

list:

  • Add data

  • Remove data

  • Change data

tuple:

  • It cannot be changed

  • Immutable

  • It can be constructed faster

dict

Associated array or map, where the data is not in order of entry.

    >>> dir(dict)
    ['__class__', '__class_getitem__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__ior__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__or__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__ror__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']

Most used operations: get, items, keys, setdefault, update, values

    # creation
    >>> data = {}
    >>> data = dict()
    >>> data = {'id1':'first', 'id2':'second'}
    >>> data = dict(id1='first', id2='second')

    # adding Data
    >>> data['id1'] = 'msg1'
    >>> data['new'] = 'msg'
    >>> data
    {'id1': 'msg1', 'id2': 'second', 'new': 'msg'}

    # updating data
    >>> data.update({'id1':'update1'})
    >>> data
    {'id1': 'update1', 'id2': 'second', 'new': 'msg’}

    # accessing Data
    >>> value = data['id1']
    >>> value = data.get('id1')
    >>> value
    'update1’

    # index must exists
    >>> value = data['idx']
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    KeyError: 'idx'

    # safer to use the get method
    >>> value = data.get('idx')
    >>> type(value)
    #<class 'NoneType'>
    
    # return a default value if a dictionary key is not available
    >>> value = data.get('idx', 'invalid')
    >>> value
    'invalid'

    # iteration Key/Value
    >>> for k in data.keys():
            v = data[k]
            print(k, '=', v)
    >>> for k,v in data.items():
        print(k, '=', v)

    # removing item given the key
    >>> data = dict(id1='first', id2='second', id3='third')
    >>> data
    {'id1': 'first', 'id2': 'second', 'id3': 'third'}
    >>> data.pop('id2')
    'second'
    >>> data
    {'id1': 'first', 'id3': 'third'}
    >>> data.popitem()
    ('id3', 'third')
    >>> data
    {'id1': 'first'}
    >>> data.clear()
    >>> data
    {}

set

An unordered list with unique values, iteratable and mutable.

    >>> dir(set)
    ['__and__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__iand__', '__init__', '__init_subclass__', '__ior__', '__isub__', '__iter__', '__ixor__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__or__', '__rand__', '__reduce__', '__reduce_ex__', '__repr__', '__ror__', '__rsub__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__xor__', 'add', 'clear', 'copy', 'difference', 'difference_update', 'discard', 'intersection', 'intersection_update', 'isdisjoint', 'issubset', 'issuperset', 'pop', 'remove', 'symmetric_difference', 'symmetric_difference_update', 'union', 'update']

Most used operations: add, clear, difference, discard, intersection, remove, union, update

    # creation
    >>> s = set()
    >>> s = set([1, 2, 3])
    >>> s = set((1, 2, 3))
    >>> s = {1, 2, 3}

    # adding Data
    >>> s=set()
    >>> s.add(1)
    >>> s.add(True)
    >>> s.add(False)
    >>> s.add('a string')
    >>> s.add('')
    >>> len(s)
    4
    >>> s
    {False, 1, 'a string', ''}

    # updating data
    >>> s = set()
    >>> s.update(1)
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module> TypeError: 'int' object is not iterable
    >>> s.update([1])
    >>> s.add([1,2,3])
    Traceback (most recent call last): File "<stdin>", line 1, in <module>
    TypeError: unhashable type: 'list'
    >>> s.update([1,2,3])

    # removing data
    >>> s.remove(1)
    >>> s.remove(1)
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module> KeyError: 1
    >>> s.discard(1)
    >>>

Methods & Operations on sets:

    # union
    >>> s1 = set([1,2,3,4,5])
    >>> s2 = set([5,6,7,8,9])
    >>> s1.union(s2)
    {1, 2, 3, 4, 5, 6, 7, 8, 9}
    >>> s1
    {1, 2, 3, 4, 5}
    >>> s2
    {5, 6, 7, 8, 9}
    
    # intersection
    >>> s1.intersection(s2)
    {5}
    >>> 5 in s1
    True
    
    # differences
    >>> s1.difference(s2)
    {1, 2, 3, 4}