PyRoma 2015
Full Name: Andrea Iuliano
Age: 25
Master Degree: Computer Science
At: UniRoma3
Passions:
Contacs:
Computer Vision Engineer
"if I can see it, It can see it"
We already have a general purpose data structures which providing a containing functions:
The most basic data structure offered by Python.
Each element is stored into a sequence space and it can be accessed by an index (eg. an integer number).
list1 = ['physics', 'chemistry', 1997, 2000];
list2 = [1, 2, 3, 4, 5 ];
list3 = ["a", "b", "c", "d"];
Also they can be used as a stack structure, offering in an easily way LIFO accessing.
>>> stack = [3, 4, 5]
>>> stack.append(6)
>>> stack.append(7)
>>> stack
[3, 4, 5, 6, 7]
>>> stack.pop()
7
>>> stack
[3, 4, 5, 6]
An immutable collection of elements. You cannot update or change the value of tuple's elements or its size.
>>> tupl = (1, 2, 3, 4, 5, 6, 7 )
>>> tupl[0]
1
>>> tupl[0] = 10
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-3-947ebd095daf> in <module>()
----> 1 tupl[0] = 10
1
TypeError: 'tuple' object does not support item assignment
It is an unordered collection with no duplicated elements. It supports mathematical operations like union, intersection and difference.
>>> set1 = set(range(0,5))
>>> set2 = set(range(3,8))
>>> set1
{0, 1, 2, 3, 4}
>>> set2
{3, 4, 5, 6, 7}
>>> set1.union(set2)
{0, 1, 2, 3, 4, 5, 6, 7}
>>> set1.intersection(set2)
{3, 4}
>>> set1.difference(set2)
{0, 1, 2}
Text
Same as set with an immutable feature
>>> frozen_set = frozenset(range(0,5))
>>> frozen_set
frozenset({0, 1, 2, 3, 4})
>>> frozen_set.
frozen_set.copy frozen_set.issubset
frozen_set.difference frozen_set.issuperset
frozen_set.intersection frozen_set.symmetric_difference
frozen_set.isdisjoint frozen_set.union
A dictionary is an unordered set of (key : value) pairs, with a unique key value.
>>> dict = {'Name': 'Valerio', 'Age': 25, 'Name': 'Andrea'};
>>> dict
{'Age': 25, 'Name': 'Andrea'}
>>> dict['Name'];
'Andrea'
>>> dict.keys()
['Age', 'Name']
>>> dict.values()
[25, 'Andrea']
" So why we need it? We have a useful primitive data structures, that we can combine as we like it! "
The correct answer is:
Introduced with Python2:
Introduced with Python3:
It is a dict subclass which can easily count hashable objects.
>>> char_counter = Counter("Hi, it works even with strings")
>>> char_counter
Counter({' ': 5, 'i': 4, 's': 3, 't': 3, 'e': 2, 'n': 2, 'r': 2, 'w': 2,
'g': 1, 'H': 1, 'k': 1, ',': 1, 'o': 1, 'v': 1, 'h': 1})
>>> string_counter = Counter(["Hi", ",", "it", "works", "even", "with",
"strings"])
>>> string_counter
Counter({'even': 1, ',': 1, 'it': 1, 'Hi': 1, 'works': 1, 'with': 1,
'strings': 1})
>>> string_counter.elements()
<itertools.chain at 0x7fe9b37ebb10>
>>> list(string_counter.elements())
['even', ',', 'it', 'Hi', 'works', 'with', 'strings']
>>> # Find the ten most common words in Hamlet
>>> import re
>>> words = re.findall(r'\w+', open('hamlet.txt').read().lower())
>>> Counter(words).most_common(10)
[('the', 1143), ('and', 966), ('to', 762), ('of', 669), ('i', 631),
('you', 554), ('a', 546), ('my', 514), ('hamlet', 471), ('in', 451)]
>>> # Some mathematicals examples
>>> c = Counter(a=3, b=1)
>>> d = Counter(a=1, b=2)
>>> c + d # add two counters together: c[x] + d[x]
Counter({'a': 4, 'b': 3})
>>> c - d # subtract (keeping only positive counts)
Counter({'a': 2})
>>> c & d # intersection: min(c[x], d[x])
Counter({'a': 1, 'b': 1})
>>> c | d # union: max(c[x], d[x])
Counter({'a': 3, 'b': 2})
A generalization of stacks and queues.
Advantages:
>>> deq = deque([], 3)
>>> deq.append(1)
>>> deq
deque([1], maxlen=3)
>>> deq.append(2)
>>> deq.append(3)
>>> deq
deque([1, 2, 3], maxlen=3)
>>> deq.append(4)
>>> deq
deque([2, 3, 4], maxlen=3)
>>> deq.appendleft(5)
>>> deq
deque([5, 2, 3], maxlen=3)
>>> #Rotations
>>> deq = deque([5, 2, 3], maxlen=3)
>>> deq.rotate(1)
>>> deq
deque([3, 5, 2], maxlen=3)
>>> deq.rotate(2)
>>> deq
deque([5, 2, 3], maxlen=3)
>>> deq.rotate(-3)
>>> deq
deque([5, 2, 3], maxlen=3)
>>> # Linux Tail Implementation
>>> def tail(filename, n):
... 'Return the last n lines of a file'
... with open(filename) as f:
... return deque(f, n)
>>> def moving_average(iterable, n=3):
... # Get an iterator from iterable object
... it = iter(iterable)
...
... # Create a deque as a n-size window
... deq = deque(itertools.islice(it, n-1))
... deq.appendleft(0)
... tot = sum(deq)
...
... # Iterate the list and get the mean for each window
... for elem in it:
... popped = deq.popleft()
... tot += elem - popped
... deq.append(elem)
... yield tot / float(n)
>>> raw_list = map(lambda x: x*5, range(0,10))
>>> print "input: ", raw_list
input: [0, 5, 10, 15, 20, 25, 30, 35, 40, 45]
>>> average = moving_average(raw_list)
>>> print "output: ", list(average)
output: [5.0, 10.0, 15.0, 20.0, 25.0, 30.0, 35.0, 40.0]
It is a dictionary like an object which provides all methods provided by dictionary with less code and the same speed.
>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
>>> d = defaultdict(list)
>>> for k, v in s:
... d[k].append(v)
...
>>> d.items()
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]
>>> #Dict of random int
>>> rand_dict = defaultdict(lambda: randint(0,3))
>>> rand_dict
defaultdict(<function <lambda> at 0x7f9254f0b1b8>, {})
>>> for num in range(5):
... rand_dict[num]
>>> rand_dict
defaultdict(<function <lambda> at 0x7f9254f0b1b8>, {0: 1, 1: 1, 2: 0, 3: 2, 4: 1})
A factory of hybrid "tuple-dictionary" object: it returns a tuple charaterized by:
>>> Point = namedtuple('Point', ['x', 'y']) # Defining the namedtuple
>>> p = Point(10, y=20) # Creating an object
>>> p
Point(x=10, y=20)
>>> p.x + p.y
30
>>> p[0] + p[1] # Accessing the values in normal way
30
>>> x, y = p # Unpacking the tuple
>>> x
10
>>> y
20
>>> Point = namedtuple('Point', ['x', 'y'], verbose=True)
class Point(tuple):
'Point(x, y)'
__slots__ = ()
_fields = ('x', 'y')
def __new__(_cls, x, y):
'Create a new instance of Point(x, y)'
return _tuple.__new__(_cls, (x, y))
@classmethod
def _make(cls, iterable, new=tuple.__new__, len=len):
'Make a new Point object from a sequence or iterable'
result = new(cls, iterable)
if len(result) != 2:
raise TypeError('Expected 2 arguments, got %d' % len(result))
return result
def __repr__(self):
'Return a nicely formatted representation string'
return 'Point(x=%r, y=%r)' % self
def _asdict(self):
'Return a new OrderedDict which maps field names to their values'
return OrderedDict(zip(self._fields, self))
def _replace(_self, **kwds):
'Return a new Point object replacing specified fields with new values'
result = _self._make(map(kwds.pop, ('x', 'y'), _self))
if kwds:
raise ValueError('Got unexpected field names: %r' % kwds.keys())
return result
def __getnewargs__(self):
'Return self as a plain tuple. Used by copy and pickle.'
return tuple(self)
__dict__ = _property(_asdict)
def __getstate__(self):
'Exclude the OrderedDict from pickling'
pass
x = _property(_itemgetter(0), doc='Alias for field number 0')
y = _property(_itemgetter(1), doc='Alias for field number 1')
A regular dictionary which is able to remember the order that items were inserted
>>> # regular unsorted dictionary
>>> d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2}
>>> # dictionary sorted by key
>>> OrderedDict(sorted(d.items(), key=lambda t: t[0]))
OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])
>>> # dictionary sorted by value
>>> OrderedDict(sorted(d.items(), key=lambda t: t[1]))
OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])
Collections offers many Abstract Base Classes to entice the use of these data structures, even if you want to build your own collection.
class collections.Container
class collections.Hashable
class collections.Sized
class collections.Callable
class collections.Iterable
class collections.Iterator
class collections.Sequence
class collections.MutableSequence
class collections.Set
class collections.MutableSet
class collections.Mapping
class collections.MutableMapping
class collections.MappingView
class collections.ItemsView
class collections.KeysView
class collections.ValuesView
It provides a quickly linking between many mappings, so they can be treated as a single unit.
Features:
>>> dict1 = { "Name": "Andrea", "Surname": "Iuliano", "Age": 25 }
>>> dict2 = { "Name": "Valerio", "Surname": "Rossi", \
"Hobbies": ["skate", "snowboard", "reptiles", "videogames"] }
>>> chain = ChainMap(dict1, dict2)
>>> chain
ChainMap({'Name': 'Andrea', 'Age': 25, 'Surname': 'Iuliano'}, \
{'Name': 'Andrea', 'Surname': 'Iuliano', \
'Hobbies': ['skate', 'snowboard', 'reptiles', 'videogames']})
>>> chain['Name']
'Andrea'
>>> chain['Hobbies']
['skate', 'snowboard', 'reptiles', 'videogames']
These three classes are wrappers around dictionary/list/string objects and allow you to treat it as a corrisponding class.
To get these functionality it needs to:
>> class User(UserDict):
...
... def __init__(self, name, surname, age):
... self.data = {}
... self.name = name
... self.surname = surname
... self.age = age
... self.update({"name":name, "surname":surname, "age":age})
...
... def changeName(self, new_name):
... self.name = new_name
... self.update({"name":new_name})
...
>>> me = User("Andres", "Iuliano", 25)
>>> me.changeName("Andrea")
>>> print(me)
{'age': 25, 'name': 'Andrea', 'surname': 'Iuliano'}
>>> print(me['age'])
25
The end, thank you!
github.com/Pausa90
andreaiuliano90@gmail.com
slides.com/pausa/deck/