Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo
Lightning Talk
collections
André Ericson
Dezembro/2011, Pug-Pe
collections
Roteiro




    • Counter
    • deque
    • namedtuple
    • OrderedDict
    • abc
    • collections.abc
collections.Counter
Counter


          >>> c = Counter([’a’, ’b’, ’c’, ’d’, ’a’, ’d’, ’b’])
          >>> print c
          Counter({’a’: 2, ’b’: 2, ’d’: 2, ’c’: 1})

          # Funciona como um dicionario
          >>> print c[’a’]
          2
          >>> c[’a’] += 1
          >>> print c
          Counter({’a’: 3, ’b’: 2, ’d’: 2, ’c’: 1})

          >>> print c[’e’] # Retorna 0 ao inves de levantar KeyError
          0

          >>> c.most_common(3)
          [(’a’, 3), (’b’, 2), (’d’, 2)]
          >>> c[’f’] = ’asdad’ # Pode adicionar qualquer coisa
          >>> print c
          Counter({’f’: ’asdad’, ’a’: 3, ’b’: 2, ’d’: 2, ’c’: 1})
          >>> c[’f’] > c[’a’]
          True

          >>> c.update([’a’, ’b’, ’b’, ’d’])
          # c.subtract(iterable-or-mapping) faz o subtracao de elementos
          >>> print c
          Counter({’f’: ’asdad’, ’a’: 4, ’b’: 4, ’d’: 3, ’c’: 1})
Counter


          >>> c = Counter([’a’, ’b’, ’c’, ’d’, ’a’, ’d’, ’b’])
          >>> print c
          Counter({’a’: 2, ’b’: 2, ’d’: 2, ’c’: 1})

          # Funciona como um dicionario
          >>> print c[’a’]
          2
          >>> c[’a’] += 1
          >>> print c
          Counter({’a’: 3, ’b’: 2, ’d’: 2, ’c’: 1})

          >>> print c[’e’] # Retorna 0 ao inves de levantar KeyError
          0

          >>> c.most_common(3)
          [(’a’, 3), (’b’, 2), (’d’, 2)]
          >>> c[’f’] = ’asdad’ # Pode adicionar qualquer coisa
          >>> print c
          Counter({’f’: ’asdad’, ’a’: 3, ’b’: 2, ’d’: 2, ’c’: 1})
          >>> c[’f’] > c[’a’]
          True

          >>> c.update([’a’, ’b’, ’b’, ’d’])
          # c.subtract(iterable-or-mapping) faz o subtracao de elementos
          >>> print c
          Counter({’f’: ’asdad’, ’a’: 4, ’b’: 4, ’d’: 3, ’c’: 1})
Counter


          >>> c = Counter([’a’, ’b’, ’c’, ’d’, ’a’, ’d’, ’b’])
          >>> print c
          Counter({’a’: 2, ’b’: 2, ’d’: 2, ’c’: 1})

          # Funciona como um dicionario
          >>> print c[’a’]
          2
          >>> c[’a’] += 1
          >>> print c
          Counter({’a’: 3, ’b’: 2, ’d’: 2, ’c’: 1})

          >>> print c[’e’] # Retorna 0 ao inves de levantar KeyError
          0

          >>> c.most_common(3)
          [(’a’, 3), (’b’, 2), (’d’, 2)]
          >>> c[’f’] = ’asdad’ # Pode adicionar qualquer coisa
          >>> print c
          Counter({’f’: ’asdad’, ’a’: 3, ’b’: 2, ’d’: 2, ’c’: 1})
          >>> c[’f’] > c[’a’]
          True

          >>> c.update([’a’, ’b’, ’b’, ’d’])
          # c.subtract(iterable-or-mapping) faz o subtracao de elementos
          >>> print c
          Counter({’f’: ’asdad’, ’a’: 4, ’b’: 4, ’d’: 3, ’c’: 1})
Counter


          >>> c = Counter([’a’, ’b’, ’c’, ’d’, ’a’, ’d’, ’b’])
          >>> print c
          Counter({’a’: 2, ’b’: 2, ’d’: 2, ’c’: 1})

          # Funciona como um dicionario
          >>> print c[’a’]
          2
          >>> c[’a’] += 1
          >>> print c
          Counter({’a’: 3, ’b’: 2, ’d’: 2, ’c’: 1})

          >>> print c[’e’] # Retorna 0 ao inves de levantar KeyError
          0

          >>> c.most_common(3)
          [(’a’, 3), (’b’, 2), (’d’, 2)]
          >>> c[’f’] = ’asdad’ # Pode adicionar qualquer coisa
          >>> print c
          Counter({’f’: ’asdad’, ’a’: 3, ’b’: 2, ’d’: 2, ’c’: 1})
          >>> c[’f’] > c[’a’]
          True

          >>> c.update([’a’, ’b’, ’b’, ’d’])
          # c.subtract(iterable-or-mapping) faz o subtracao de elementos
          >>> print c
          Counter({’f’: ’asdad’, ’a’: 4, ’b’: 4, ’d’: 3, ’c’: 1})
Counter


          >>> c = Counter([’a’, ’b’, ’c’, ’d’, ’a’, ’d’, ’b’])
          >>> print c
          Counter({’a’: 2, ’b’: 2, ’d’: 2, ’c’: 1})

          # Funciona como um dicionario
          >>> print c[’a’]
          2
          >>> c[’a’] += 1
          >>> print c
          Counter({’a’: 3, ’b’: 2, ’d’: 2, ’c’: 1})

          >>> print c[’e’] # Retorna 0 ao inves de levantar KeyError
          0

          >>> c.most_common(3)
          [(’a’, 3), (’b’, 2), (’d’, 2)]
          >>> c[’f’] = ’asdad’ # Pode adicionar qualquer coisa
          >>> print c
          Counter({’f’: ’asdad’, ’a’: 3, ’b’: 2, ’d’: 2, ’c’: 1})
          >>> c[’f’] > c[’a’]
          True

          >>> c.update([’a’, ’b’, ’b’, ’d’])
          # c.subtract(iterable-or-mapping) faz o subtracao de elementos
          >>> print c
          Counter({’f’: ’asdad’, ’a’: 4, ’b’: 4, ’d’: 3, ’c’: 1})
Counter: Exemplo

  import re
  from collections import Counter
  LANGUAGES = [
      "C", "C++", "Java", "PHP", "Ruby", "C#",
      "JavaScript", "Perl", "Python"
  ]

  swear_book = [
      ’shit’, ’piss’, ’fuck’,
      ’cock’, ’motherfucker’,                                    Counter({’C++’: 67, ’Ruby’: 64,
  ]                                                                      ’JavaScript’: 55, ’C’: 39,
                                                                         ’Perl’: 33, ’C#’: 29,
  lang_count = Counter()                                                 ’Java’: 23, ’Python’: 15,
  swear_count = Counter()                                                ’PHP’: 11})
                                                                 Counter({’shit’: 213, ’fuck’: 112,
  for lang in LANGUAGES:                                                 ’piss’: 5, ’cock’: 4,
      with open(’language-commits[’ + lang +                             ’motherfucker’: 2})
                  ’].yml’) as f:
          words = re.findall(’w+’, f.read().lower())
          for fu in words:
              if fu in swear_book:
                  lang_count[lang] += 1
                  swear_count[fu] += 1

  print lang_count
  print swear_count
                            data from: https://github.com/AndrewVos/github-statistics
collections.deque
deque




img: http://www.webreference.com
deque




  • lists são lentas para pop(0) e insert(0, v) --> O(n)
  • deque pop e insert no fim ou no início com O(1)
  • deque não substitui list
deque



  >>> d = deque([1,2,3])
  >>> print d
  deque([1, 2, 3])

  >>> d.append(4)
  >>> print d
  deque([1, 2, 3, 4])        >>> d.rotate(1) # Rotaciona a direita
                             >>> print d
  >>> d.appendleft(5)        deque([9, 1, 3, 7, 8])
  >>> print d
  deque([5, 1, 2, 3, 4])     >>> d = deque([1,2,3], maxlen=3)
                             >>> print d
  >>> d.pop(), d.popleft()   deque([1, 2, 3], maxlen=3)
  (4, 5)                     >>> d.append(4)
  >>> del d[1]               deque([2, 3, 4], maxlen=3)
  >>> print d
  deque([1, 3])

  >>> d.extend([7, 8, 9])
  >>> print d
  deque([1, 3, 7, 8, 9])
deque



  >>> d = deque([1,2,3])
  >>> print d
  deque([1, 2, 3])

  >>> d.append(4)
  >>> print d
  deque([1, 2, 3, 4])        >>> d.rotate(1) # Rotaciona a direita
                             >>> print d
  >>> d.appendleft(5)        deque([9, 1, 3, 7, 8])
  >>> print d
  deque([5, 1, 2, 3, 4])     >>> d = deque([1,2,3], maxlen=3)
                             >>> print d
  >>> d.pop(), d.popleft()   deque([1, 2, 3], maxlen=3)
  (4, 5)                     >>> d.append(4)
  >>> del d[1]               deque([2, 3, 4], maxlen=3)
  >>> print d
  deque([1, 3])

  >>> d.extend([7, 8, 9])
  >>> print d
  deque([1, 3, 7, 8, 9])
deque



  >>> d = deque([1,2,3])
  >>> print d
  deque([1, 2, 3])

  >>> d.append(4)
  >>> print d
  deque([1, 2, 3, 4])        >>> d.rotate(1) # Rotaciona a direita
                             >>> print d
  >>> d.appendleft(5)        deque([9, 1, 3, 7, 8])
  >>> print d
  deque([5, 1, 2, 3, 4])     >>> d = deque([1,2,3], maxlen=3)
                             >>> print d
  >>> d.pop(), d.popleft()   deque([1, 2, 3], maxlen=3)
  (4, 5)                     >>> d.append(4)
  >>> del d[1]               deque([2, 3, 4], maxlen=3)
  >>> print d
  deque([1, 3])

  >>> d.extend([7, 8, 9])
  >>> print d
  deque([1, 3, 7, 8, 9])
deque



  >>> d = deque([1,2,3])
  >>> print d
  deque([1, 2, 3])

  >>> d.append(4)
  >>> print d
  deque([1, 2, 3, 4])        >>> d.rotate(1) # Rotaciona a direita
                             >>> print d
  >>> d.appendleft(5)        deque([9, 1, 3, 7, 8])
  >>> print d
  deque([5, 1, 2, 3, 4])     >>> d = deque([1,2,3], maxlen=3)
                             >>> print d
  >>> d.pop(), d.popleft()   deque([1, 2, 3], maxlen=3)
  (4, 5)                     >>> d.append(4)
  >>> del d[1]               deque([2, 3, 4], maxlen=3)
  >>> print d
  deque([1, 3])

  >>> d.extend([7, 8, 9])
  >>> print d
  deque([1, 3, 7, 8, 9])
deque



  >>> d = deque([1,2,3])
  >>> print d
  deque([1, 2, 3])

  >>> d.append(4)
  >>> print d
  deque([1, 2, 3, 4])        >>> d.rotate(1) # Rotaciona a direita
                             >>> print d
  >>> d.appendleft(5)        deque([9, 1, 3, 7, 8])
  >>> print d
  deque([5, 1, 2, 3, 4])     >>> d = deque([1,2,3], maxlen=3)
                             >>> print d
  >>> d.pop(), d.popleft()   deque([1, 2, 3], maxlen=3)
  (4, 5)                     >>> d.append(4)
  >>> del d[1]               deque([2, 3, 4], maxlen=3)
  >>> print d
  deque([1, 3])

  >>> d.extend([7, 8, 9])
  >>> print d
  deque([1, 3, 7, 8, 9])
deque



  >>> d = deque([1,2,3])
  >>> print d
  deque([1, 2, 3])

  >>> d.append(4)
  >>> print d
  deque([1, 2, 3, 4])        >>> d.rotate(1) # Rotaciona a direita
                             >>> print d
  >>> d.appendleft(5)        deque([9, 1, 3, 7, 8])
  >>> print d
  deque([5, 1, 2, 3, 4])     >>> d = deque([1,2,3], maxlen=3)
                             >>> print d
  >>> d.pop(), d.popleft()   deque([1, 2, 3], maxlen=3)
  (4, 5)                     >>> d.append(4)
  >>> del d[1]               deque([2, 3, 4], maxlen=3)
  >>> print d
  deque([1, 3])

  >>> d.extend([7, 8, 9])
  >>> print d
  deque([1, 3, 7, 8, 9])
deque



  >>> d = deque([1,2,3])
  >>> print d
  deque([1, 2, 3])

  >>> d.append(4)
  >>> print d
  deque([1, 2, 3, 4])        >>> d.rotate(1) # Rotaciona a direita
                             >>> print d
  >>> d.appendleft(5)        deque([9, 1, 3, 7, 8])
  >>> print d
  deque([5, 1, 2, 3, 4])     >>> d = deque([1,2,3], maxlen=3)
                             >>> print d
  >>> d.pop(), d.popleft()   deque([1, 2, 3], maxlen=3)
  (4, 5)                     >>> d.append(4)
  >>> del d[1]               deque([2, 3, 4], maxlen=3)
  >>> print d
  deque([1, 3])

  >>> d.extend([7, 8, 9])
  >>> print d
  deque([1, 3, 7, 8, 9])
deque vs list


   num =   100000
   print   u"Tempo para insercao no inicio:"
   print   "Deque:",
   print   timeit.Timer(’dq.appendleft("abc")’,
                         ’from collections import deque;’+
                        ’dq = deque()’).timeit(number=num)
   print   "List:",
   print   timeit.Timer(’li.insert(0, "abc")’,
                         ’li =[]’).timeit(number=num)       Tempo para insercao no inicio:
   print   "Tempo para pop(0):"                             Deque: 0.0206291675568
   print   "Deque:",                                        List: 5.03016710281
   print   timeit.Timer(’dq.popleft()’,                     ----------
                       ’from collections import deque;’+    Tempo para pop(0):
                        ’dq = deque(range(%i))’ % num       Deque: 0.0202388763428
                       ).timeit(number=num)                 List: 3.49450302124
   print   "List:",                                         ----------
   print   timeit.Timer(’li.pop(0)’,                        Tempo de acesso ao meio:
                         ’li = range(%i)’ % num             Deque: 4.97369003296
                       ).timeit(number=num)                 List: 0.051794052124
   print   "Tempo de acesso ao meio:"
   print   "Deque:",
   print   timeit.Timer(’dq[meio]’, ’from collections import deque;’+
                                    ’dq = deque(range(%i));’ % num +
                                    ’meio = len(dq)/2’).timeit()
   print   "List:",
   print   timeit.Timer(’li[meio]’, ’li = range(%i);’ % num +
                                    ’meio = len(li)/2’).timeit()
collections.namedtuple
namedtuple



             >>> Point = namedtuple(’Point’, [’x’, ’y’])
             >>> p = Point(2, 3)
             >>> print p.x, p.y
             2 3

             >>> print p[0:2]
             (2, 3)
             >>> print p.count(2) # herda metodos de tuple
             1

             >>> Point._make([1,2])
             Point(x=1, y=2)

             >>> p._asdict()
             OrderedDict([(’x’, 2), (’y’, 3)])

             >>> p._replace(x=77)
             Point(x=77, y=3)

             >>> p._fields
             (’x’, ’y’)
namedtuple



             >>> Point = namedtuple(’Point’, [’x’, ’y’])
             >>> p = Point(2, 3)
             >>> print p.x, p.y
             2 3

             >>> print p[0:2]
             (2, 3)
             >>> print p.count(2) # herda metodos de tuple
             1

             >>> Point._make([1,2])
             Point(x=1, y=2)

             >>> p._asdict()
             OrderedDict([(’x’, 2), (’y’, 3)])

             >>> p._replace(x=77)
             Point(x=77, y=3)

             >>> p._fields
             (’x’, ’y’)
namedtuple



             >>> Point = namedtuple(’Point’, [’x’, ’y’])
             >>> p = Point(2, 3)
             >>> print p.x, p.y
             2 3

             >>> print p[0:2]
             (2, 3)
             >>> print p.count(2) # herda metodos de tuple
             1

             >>> Point._make([1,2])
             Point(x=1, y=2)

             >>> p._asdict()
             OrderedDict([(’x’, 2), (’y’, 3)])

             >>> p._replace(x=77)
             Point(x=77, y=3)

             >>> p._fields
             (’x’, ’y’)
namedtuple



             >>> Point = namedtuple(’Point’, [’x’, ’y’])
             >>> p = Point(2, 3)
             >>> print p.x, p.y
             2 3

             >>> print p[0:2]
             (2, 3)
             >>> print p.count(2) # herda metodos de tuple
             1

             >>> Point._make([1,2])
             Point(x=1, y=2)

             >>> p._asdict()
             OrderedDict([(’x’, 2), (’y’, 3)])

             >>> p._replace(x=77)
             Point(x=77, y=3)

             >>> p._fields
             (’x’, ’y’)
namedtuple



             >>> Point = namedtuple(’Point’, [’x’, ’y’])
             >>> p = Point(2, 3)
             >>> print p.x, p.y
             2 3

             >>> print p[0:2]
             (2, 3)
             >>> print p.count(2) # herda metodos de tuple
             1

             >>> Point._make([1,2])
             Point(x=1, y=2)

             >>> p._asdict()
             OrderedDict([(’x’, 2), (’y’, 3)])

             >>> p._replace(x=77)
             Point(x=77, y=3)

             >>> p._fields
             (’x’, ’y’)
namedtuple



             >>> Point = namedtuple(’Point’, [’x’, ’y’])
             >>> p = Point(2, 3)
             >>> print p.x, p.y
             2 3

             >>> print p[0:2]
             (2, 3)
             >>> print p.count(2) # herda metodos de tuple
             1

             >>> Point._make([1,2])
             Point(x=1, y=2)

             >>> p._asdict()
             OrderedDict([(’x’, 2), (’y’, 3)])

             >>> p._replace(x=77)
             Point(x=77, y=3)

             >>> p._fields
             (’x’, ’y’)
collections.OrderedDict
OrderedDict




              >>> d = {’banana’: 3, ’apple’:4, ’pear’: 1, ’orange’: 2}
              >>> print d
              {’orange’: 2, ’pear’: 1, ’banana’: 3, ’apple’: 4}

              >>> print OrderedDict(sorted(d.items()))
              OrderedDict([(’apple’, 4), (’banana’, 3), (’orange’, 2), (’pear’, 1)])

              >>> od = OrderedDict(sorted(d.items(), key=lambda k: k[1]))
              >>> print od
              OrderedDict([(’pear’, 1), (’orange’, 2), (’banana’, 3), (’apple’, 4)])

              >>> od.popitem()
              (’apple’, 4)
              >>> print od
              OrderedDict([(’pear’, 1), (’orange’, 2), (’banana’, 3)])
OrderedDict




              >>> d = {’banana’: 3, ’apple’:4, ’pear’: 1, ’orange’: 2}
              >>> print d
              {’orange’: 2, ’pear’: 1, ’banana’: 3, ’apple’: 4}

              >>> print OrderedDict(sorted(d.items()))
              OrderedDict([(’apple’, 4), (’banana’, 3), (’orange’, 2), (’pear’, 1)])

              >>> od = OrderedDict(sorted(d.items(), key=lambda k: k[1]))
              >>> print od
              OrderedDict([(’pear’, 1), (’orange’, 2), (’banana’, 3), (’apple’, 4)])

              >>> od.popitem()
              (’apple’, 4)
              >>> print od
              OrderedDict([(’pear’, 1), (’orange’, 2), (’banana’, 3)])
OrderedDict




              >>> d = {’banana’: 3, ’apple’:4, ’pear’: 1, ’orange’: 2}
              >>> print d
              {’orange’: 2, ’pear’: 1, ’banana’: 3, ’apple’: 4}

              >>> print OrderedDict(sorted(d.items()))
              OrderedDict([(’apple’, 4), (’banana’, 3), (’orange’, 2), (’pear’, 1)])

              >>> od = OrderedDict(sorted(d.items(), key=lambda k: k[1]))
              >>> print od
              OrderedDict([(’pear’, 1), (’orange’, 2), (’banana’, 3), (’apple’, 4)])

              >>> od.popitem()
              (’apple’, 4)
              >>> print od
              OrderedDict([(’pear’, 1), (’orange’, 2), (’banana’, 3)])
OrderedDict




              >>> d = {’banana’: 3, ’apple’:4, ’pear’: 1, ’orange’: 2}
              >>> print d
              {’orange’: 2, ’pear’: 1, ’banana’: 3, ’apple’: 4}

              >>> print OrderedDict(sorted(d.items()))
              OrderedDict([(’apple’, 4), (’banana’, 3), (’orange’, 2), (’pear’, 1)])

              >>> od = OrderedDict(sorted(d.items(), key=lambda k: k[1]))
              >>> print od
              OrderedDict([(’pear’, 1), (’orange’, 2), (’banana’, 3), (’apple’, 4)])

              >>> od.popitem()
              (’apple’, 4)
              >>> print od
              OrderedDict([(’pear’, 1), (’orange’, 2), (’banana’, 3)])
collections.abc
  ABC - Abstract Base Class
abc em 2 minutos



            class AbstractKnight(object):

               __metaclass__ = abc.ABCMeta
               @abc.abstractmethod
               def echo(self):
                   pass

            class IncompKnight(AbstractKnight):
                pass

            >>> IncompKnight()
            TypeError: Can’t instantiate abstract class IncompKnight
            with abstract methods echo

            >>> AbstractKnight.__abstractmethods__
            frozenset([’echo’])

            class KnightImp(AbstractKnight):
                def echo(self):
                    print ’Ni’
            >>> KnightImp().echo()
            Ni
abc em 2 minutos



            class AbstractKnight(object):

               __metaclass__ = abc.ABCMeta
               @abc.abstractmethod
               def echo(self):
                   pass

            class IncompKnight(AbstractKnight):
                pass

            >>> IncompKnight()
            TypeError: Can’t instantiate abstract class IncompKnight
            with abstract methods echo

            >>> AbstractKnight.__abstractmethods__
            frozenset([’echo’])

            class KnightImp(AbstractKnight):
                def echo(self):
                    print ’Ni’
            >>> KnightImp().echo()
            Ni
abc em 2 minutos



            class AbstractKnight(object):

               __metaclass__ = abc.ABCMeta
               @abc.abstractmethod
               def echo(self):
                   pass

            class IncompKnight(AbstractKnight):
                pass

            >>> IncompKnight()
            TypeError: Can’t instantiate abstract class IncompKnight
            with abstract methods echo

            >>> AbstractKnight.__abstractmethods__
            frozenset([’echo’])

            class KnightImp(AbstractKnight):
                def echo(self):
                    print ’Ni’
            >>> KnightImp().echo()
            Ni
abc em 2 minutos



            class AbstractKnight(object):

               __metaclass__ = abc.ABCMeta
               @abc.abstractmethod
               def echo(self):
                   pass

            class IncompKnight(AbstractKnight):
                pass

            >>> IncompKnight()
            TypeError: Can’t instantiate abstract class IncompKnight
            with abstract methods echo

            >>> AbstractKnight.__abstractmethods__
            frozenset([’echo’])

            class KnightImp(AbstractKnight):
                def echo(self):
                    print ’Ni’
            >>> KnightImp().echo()
            Ni
abc em 2 minutos



            class AbstractKnight(object):

               __metaclass__ = abc.ABCMeta
               @abc.abstractmethod
               def echo(self):
                   pass

            class IncompKnight(AbstractKnight):
                pass

            >>> IncompKnight()
            TypeError: Can’t instantiate abstract class IncompKnight
            with abstract methods echo

            >>> AbstractKnight.__abstractmethods__
            frozenset([’echo’])

            class KnightImp(AbstractKnight):
                def echo(self):
                    print ’Ni’
            >>> KnightImp().echo()
            Ni
Herdando dict




            class Dicto(dict):
                def __getitem__(self, k):
                    return 31

            >>> d = Dicto()
            >>> d[2]
            31

            >>> print d.get(2)
            None

            D’oh : (
Herdando dict




            class Dicto(dict):
                def __getitem__(self, k):
                    return 31

            >>> d = Dicto()
            >>> d[2]
            31

            >>> print d.get(2)
            None

            D’oh : (
Herdando dict




            class Dicto(dict):
                def __getitem__(self, k):
                    return 31

            >>> d = Dicto()
            >>> d[2]
            31

            >>> print d.get(2)
            None

            D’oh : (
collections.abc




   • subclasses de builtin containers nem sempre produzem resultados
    esperados
   • subclasses de ABC produzem
collections.abc
if you’re lazy



                                                    Callable -> [’__call__’]
                                                    Container -> [’__contains__’]
                                                    Hashable -> [’__hash__’]
                                                    ItemsView -> []
                                                    Iterable -> [’__iter__’]
     # ex: MutableMapping.__abstractmethods__       Iterator -> [’next’]
     for i in dir(collections):                     KeysView -> []
         try:                                       Mapping -> [’__iter__’, ’__getitem__’, ’__len__’]
              meths = list(getattr(collections, i   MappingView -> []
                          ).__abstractmethods__)    MutableMapping -> [’__delitem__’, ’__setitem__’,
              print i, ’->’, meths                                   ’__getitem__’, ’__iter__’, ’__len__’]
         except:                                    MutableSequence -> [’__delitem__’, ’__setitem__’,
              pass                                                   ’__getitem__’, ’__len__’, ’insert’]
                                                    MutableSet -> [’discard’, ’add’, ’__iter__’,
                                                                     ’__len__’, ’__contains__’]
                                                    Sequence -> [’__getitem__’, ’__len__’]
                                                    Set -> [’__iter__’, ’__len__’, ’__contains__’]
                                                    Sized -> [’__len__’]
                                                    ValuesView -> []
Subclassing dict de
collections.MutableMapping


    from collections import MutableMapping

    class Dicto(MutableMapping):

       def __init__(self):
           self.d = {}                       >>> d = Dicto()
                                             >>> d[’eggs’] = ’ovos’
       def __delitem__(self, i):             >>> d[’ham’] = ’presunto’
           del self.d[i]                     >>> for i in d:
                                             ...    print i + ’:’ + d[i]
       def __setitem__(self, k, v):          eggs:ovos
           self.d[k.lower()] = v             ham:presunto
                                             >>> d.get(’HaM’)
       def __getitem__(self, k):             presunto
           return self.d[k.lower()]          >>> d[’eGGs’]
                                             ’ovos’
       def __iter__(self):
           return iter(self.d)

       def __len__(self):
           return len(self.d)
Subclassing dict de
collections.MutableMapping


    from collections import MutableMapping

    class Dicto(MutableMapping):

       def __init__(self):
           self.d = {}                       >>> d = Dicto()
                                             >>> d[’eggs’] = ’ovos’
       def __delitem__(self, i):             >>> d[’ham’] = ’presunto’
           del self.d[i]                     >>> for i in d:
                                             ...    print i + ’:’ + d[i]
       def __setitem__(self, k, v):          eggs:ovos
           self.d[k.lower()] = v             ham:presunto
                                             >>> d.get(’HaM’)
       def __getitem__(self, k):             presunto
           return self.d[k.lower()]          >>> d[’eGGs’]
                                             ’ovos’
       def __iter__(self):
           return iter(self.d)

       def __len__(self):
           return len(self.d)
Referência


  • Lightning Talk de:




    no fisl 2011.
  • The Data Structures of Python, Alex Gaynor no PyCon2011
  • http://www.doughellmann.com/PyMOTW/abc/index.html
  • http://docs.python.org/library/collections.html
Dúvidas?




                     André Ericson
           http://www.github.com/aericson
                de.ericson@gmail.com
                      @_aericson

More Related Content

Palestra sobre Collections com Python

  • 2. collections Roteiro • Counter • deque • namedtuple • OrderedDict • abc • collections.abc
  • 4. Counter >>> c = Counter([’a’, ’b’, ’c’, ’d’, ’a’, ’d’, ’b’]) >>> print c Counter({’a’: 2, ’b’: 2, ’d’: 2, ’c’: 1}) # Funciona como um dicionario >>> print c[’a’] 2 >>> c[’a’] += 1 >>> print c Counter({’a’: 3, ’b’: 2, ’d’: 2, ’c’: 1}) >>> print c[’e’] # Retorna 0 ao inves de levantar KeyError 0 >>> c.most_common(3) [(’a’, 3), (’b’, 2), (’d’, 2)] >>> c[’f’] = ’asdad’ # Pode adicionar qualquer coisa >>> print c Counter({’f’: ’asdad’, ’a’: 3, ’b’: 2, ’d’: 2, ’c’: 1}) >>> c[’f’] > c[’a’] True >>> c.update([’a’, ’b’, ’b’, ’d’]) # c.subtract(iterable-or-mapping) faz o subtracao de elementos >>> print c Counter({’f’: ’asdad’, ’a’: 4, ’b’: 4, ’d’: 3, ’c’: 1})
  • 5. Counter >>> c = Counter([’a’, ’b’, ’c’, ’d’, ’a’, ’d’, ’b’]) >>> print c Counter({’a’: 2, ’b’: 2, ’d’: 2, ’c’: 1}) # Funciona como um dicionario >>> print c[’a’] 2 >>> c[’a’] += 1 >>> print c Counter({’a’: 3, ’b’: 2, ’d’: 2, ’c’: 1}) >>> print c[’e’] # Retorna 0 ao inves de levantar KeyError 0 >>> c.most_common(3) [(’a’, 3), (’b’, 2), (’d’, 2)] >>> c[’f’] = ’asdad’ # Pode adicionar qualquer coisa >>> print c Counter({’f’: ’asdad’, ’a’: 3, ’b’: 2, ’d’: 2, ’c’: 1}) >>> c[’f’] > c[’a’] True >>> c.update([’a’, ’b’, ’b’, ’d’]) # c.subtract(iterable-or-mapping) faz o subtracao de elementos >>> print c Counter({’f’: ’asdad’, ’a’: 4, ’b’: 4, ’d’: 3, ’c’: 1})
  • 6. Counter >>> c = Counter([’a’, ’b’, ’c’, ’d’, ’a’, ’d’, ’b’]) >>> print c Counter({’a’: 2, ’b’: 2, ’d’: 2, ’c’: 1}) # Funciona como um dicionario >>> print c[’a’] 2 >>> c[’a’] += 1 >>> print c Counter({’a’: 3, ’b’: 2, ’d’: 2, ’c’: 1}) >>> print c[’e’] # Retorna 0 ao inves de levantar KeyError 0 >>> c.most_common(3) [(’a’, 3), (’b’, 2), (’d’, 2)] >>> c[’f’] = ’asdad’ # Pode adicionar qualquer coisa >>> print c Counter({’f’: ’asdad’, ’a’: 3, ’b’: 2, ’d’: 2, ’c’: 1}) >>> c[’f’] > c[’a’] True >>> c.update([’a’, ’b’, ’b’, ’d’]) # c.subtract(iterable-or-mapping) faz o subtracao de elementos >>> print c Counter({’f’: ’asdad’, ’a’: 4, ’b’: 4, ’d’: 3, ’c’: 1})
  • 7. Counter >>> c = Counter([’a’, ’b’, ’c’, ’d’, ’a’, ’d’, ’b’]) >>> print c Counter({’a’: 2, ’b’: 2, ’d’: 2, ’c’: 1}) # Funciona como um dicionario >>> print c[’a’] 2 >>> c[’a’] += 1 >>> print c Counter({’a’: 3, ’b’: 2, ’d’: 2, ’c’: 1}) >>> print c[’e’] # Retorna 0 ao inves de levantar KeyError 0 >>> c.most_common(3) [(’a’, 3), (’b’, 2), (’d’, 2)] >>> c[’f’] = ’asdad’ # Pode adicionar qualquer coisa >>> print c Counter({’f’: ’asdad’, ’a’: 3, ’b’: 2, ’d’: 2, ’c’: 1}) >>> c[’f’] > c[’a’] True >>> c.update([’a’, ’b’, ’b’, ’d’]) # c.subtract(iterable-or-mapping) faz o subtracao de elementos >>> print c Counter({’f’: ’asdad’, ’a’: 4, ’b’: 4, ’d’: 3, ’c’: 1})
  • 8. Counter >>> c = Counter([’a’, ’b’, ’c’, ’d’, ’a’, ’d’, ’b’]) >>> print c Counter({’a’: 2, ’b’: 2, ’d’: 2, ’c’: 1}) # Funciona como um dicionario >>> print c[’a’] 2 >>> c[’a’] += 1 >>> print c Counter({’a’: 3, ’b’: 2, ’d’: 2, ’c’: 1}) >>> print c[’e’] # Retorna 0 ao inves de levantar KeyError 0 >>> c.most_common(3) [(’a’, 3), (’b’, 2), (’d’, 2)] >>> c[’f’] = ’asdad’ # Pode adicionar qualquer coisa >>> print c Counter({’f’: ’asdad’, ’a’: 3, ’b’: 2, ’d’: 2, ’c’: 1}) >>> c[’f’] > c[’a’] True >>> c.update([’a’, ’b’, ’b’, ’d’]) # c.subtract(iterable-or-mapping) faz o subtracao de elementos >>> print c Counter({’f’: ’asdad’, ’a’: 4, ’b’: 4, ’d’: 3, ’c’: 1})
  • 9. Counter: Exemplo import re from collections import Counter LANGUAGES = [ "C", "C++", "Java", "PHP", "Ruby", "C#", "JavaScript", "Perl", "Python" ] swear_book = [ ’shit’, ’piss’, ’fuck’, ’cock’, ’motherfucker’, Counter({’C++’: 67, ’Ruby’: 64, ] ’JavaScript’: 55, ’C’: 39, ’Perl’: 33, ’C#’: 29, lang_count = Counter() ’Java’: 23, ’Python’: 15, swear_count = Counter() ’PHP’: 11}) Counter({’shit’: 213, ’fuck’: 112, for lang in LANGUAGES: ’piss’: 5, ’cock’: 4, with open(’language-commits[’ + lang + ’motherfucker’: 2}) ’].yml’) as f: words = re.findall(’w+’, f.read().lower()) for fu in words: if fu in swear_book: lang_count[lang] += 1 swear_count[fu] += 1 print lang_count print swear_count data from: https://github.com/AndrewVos/github-statistics
  • 12. deque • lists são lentas para pop(0) e insert(0, v) --> O(n) • deque pop e insert no fim ou no início com O(1) • deque não substitui list
  • 13. deque >>> d = deque([1,2,3]) >>> print d deque([1, 2, 3]) >>> d.append(4) >>> print d deque([1, 2, 3, 4]) >>> d.rotate(1) # Rotaciona a direita >>> print d >>> d.appendleft(5) deque([9, 1, 3, 7, 8]) >>> print d deque([5, 1, 2, 3, 4]) >>> d = deque([1,2,3], maxlen=3) >>> print d >>> d.pop(), d.popleft() deque([1, 2, 3], maxlen=3) (4, 5) >>> d.append(4) >>> del d[1] deque([2, 3, 4], maxlen=3) >>> print d deque([1, 3]) >>> d.extend([7, 8, 9]) >>> print d deque([1, 3, 7, 8, 9])
  • 14. deque >>> d = deque([1,2,3]) >>> print d deque([1, 2, 3]) >>> d.append(4) >>> print d deque([1, 2, 3, 4]) >>> d.rotate(1) # Rotaciona a direita >>> print d >>> d.appendleft(5) deque([9, 1, 3, 7, 8]) >>> print d deque([5, 1, 2, 3, 4]) >>> d = deque([1,2,3], maxlen=3) >>> print d >>> d.pop(), d.popleft() deque([1, 2, 3], maxlen=3) (4, 5) >>> d.append(4) >>> del d[1] deque([2, 3, 4], maxlen=3) >>> print d deque([1, 3]) >>> d.extend([7, 8, 9]) >>> print d deque([1, 3, 7, 8, 9])
  • 15. deque >>> d = deque([1,2,3]) >>> print d deque([1, 2, 3]) >>> d.append(4) >>> print d deque([1, 2, 3, 4]) >>> d.rotate(1) # Rotaciona a direita >>> print d >>> d.appendleft(5) deque([9, 1, 3, 7, 8]) >>> print d deque([5, 1, 2, 3, 4]) >>> d = deque([1,2,3], maxlen=3) >>> print d >>> d.pop(), d.popleft() deque([1, 2, 3], maxlen=3) (4, 5) >>> d.append(4) >>> del d[1] deque([2, 3, 4], maxlen=3) >>> print d deque([1, 3]) >>> d.extend([7, 8, 9]) >>> print d deque([1, 3, 7, 8, 9])
  • 16. deque >>> d = deque([1,2,3]) >>> print d deque([1, 2, 3]) >>> d.append(4) >>> print d deque([1, 2, 3, 4]) >>> d.rotate(1) # Rotaciona a direita >>> print d >>> d.appendleft(5) deque([9, 1, 3, 7, 8]) >>> print d deque([5, 1, 2, 3, 4]) >>> d = deque([1,2,3], maxlen=3) >>> print d >>> d.pop(), d.popleft() deque([1, 2, 3], maxlen=3) (4, 5) >>> d.append(4) >>> del d[1] deque([2, 3, 4], maxlen=3) >>> print d deque([1, 3]) >>> d.extend([7, 8, 9]) >>> print d deque([1, 3, 7, 8, 9])
  • 17. deque >>> d = deque([1,2,3]) >>> print d deque([1, 2, 3]) >>> d.append(4) >>> print d deque([1, 2, 3, 4]) >>> d.rotate(1) # Rotaciona a direita >>> print d >>> d.appendleft(5) deque([9, 1, 3, 7, 8]) >>> print d deque([5, 1, 2, 3, 4]) >>> d = deque([1,2,3], maxlen=3) >>> print d >>> d.pop(), d.popleft() deque([1, 2, 3], maxlen=3) (4, 5) >>> d.append(4) >>> del d[1] deque([2, 3, 4], maxlen=3) >>> print d deque([1, 3]) >>> d.extend([7, 8, 9]) >>> print d deque([1, 3, 7, 8, 9])
  • 18. deque >>> d = deque([1,2,3]) >>> print d deque([1, 2, 3]) >>> d.append(4) >>> print d deque([1, 2, 3, 4]) >>> d.rotate(1) # Rotaciona a direita >>> print d >>> d.appendleft(5) deque([9, 1, 3, 7, 8]) >>> print d deque([5, 1, 2, 3, 4]) >>> d = deque([1,2,3], maxlen=3) >>> print d >>> d.pop(), d.popleft() deque([1, 2, 3], maxlen=3) (4, 5) >>> d.append(4) >>> del d[1] deque([2, 3, 4], maxlen=3) >>> print d deque([1, 3]) >>> d.extend([7, 8, 9]) >>> print d deque([1, 3, 7, 8, 9])
  • 19. deque >>> d = deque([1,2,3]) >>> print d deque([1, 2, 3]) >>> d.append(4) >>> print d deque([1, 2, 3, 4]) >>> d.rotate(1) # Rotaciona a direita >>> print d >>> d.appendleft(5) deque([9, 1, 3, 7, 8]) >>> print d deque([5, 1, 2, 3, 4]) >>> d = deque([1,2,3], maxlen=3) >>> print d >>> d.pop(), d.popleft() deque([1, 2, 3], maxlen=3) (4, 5) >>> d.append(4) >>> del d[1] deque([2, 3, 4], maxlen=3) >>> print d deque([1, 3]) >>> d.extend([7, 8, 9]) >>> print d deque([1, 3, 7, 8, 9])
  • 20. deque vs list num = 100000 print u"Tempo para insercao no inicio:" print "Deque:", print timeit.Timer(’dq.appendleft("abc")’, ’from collections import deque;’+ ’dq = deque()’).timeit(number=num) print "List:", print timeit.Timer(’li.insert(0, "abc")’, ’li =[]’).timeit(number=num) Tempo para insercao no inicio: print "Tempo para pop(0):" Deque: 0.0206291675568 print "Deque:", List: 5.03016710281 print timeit.Timer(’dq.popleft()’, ---------- ’from collections import deque;’+ Tempo para pop(0): ’dq = deque(range(%i))’ % num Deque: 0.0202388763428 ).timeit(number=num) List: 3.49450302124 print "List:", ---------- print timeit.Timer(’li.pop(0)’, Tempo de acesso ao meio: ’li = range(%i)’ % num Deque: 4.97369003296 ).timeit(number=num) List: 0.051794052124 print "Tempo de acesso ao meio:" print "Deque:", print timeit.Timer(’dq[meio]’, ’from collections import deque;’+ ’dq = deque(range(%i));’ % num + ’meio = len(dq)/2’).timeit() print "List:", print timeit.Timer(’li[meio]’, ’li = range(%i);’ % num + ’meio = len(li)/2’).timeit()
  • 22. namedtuple >>> Point = namedtuple(’Point’, [’x’, ’y’]) >>> p = Point(2, 3) >>> print p.x, p.y 2 3 >>> print p[0:2] (2, 3) >>> print p.count(2) # herda metodos de tuple 1 >>> Point._make([1,2]) Point(x=1, y=2) >>> p._asdict() OrderedDict([(’x’, 2), (’y’, 3)]) >>> p._replace(x=77) Point(x=77, y=3) >>> p._fields (’x’, ’y’)
  • 23. namedtuple >>> Point = namedtuple(’Point’, [’x’, ’y’]) >>> p = Point(2, 3) >>> print p.x, p.y 2 3 >>> print p[0:2] (2, 3) >>> print p.count(2) # herda metodos de tuple 1 >>> Point._make([1,2]) Point(x=1, y=2) >>> p._asdict() OrderedDict([(’x’, 2), (’y’, 3)]) >>> p._replace(x=77) Point(x=77, y=3) >>> p._fields (’x’, ’y’)
  • 24. namedtuple >>> Point = namedtuple(’Point’, [’x’, ’y’]) >>> p = Point(2, 3) >>> print p.x, p.y 2 3 >>> print p[0:2] (2, 3) >>> print p.count(2) # herda metodos de tuple 1 >>> Point._make([1,2]) Point(x=1, y=2) >>> p._asdict() OrderedDict([(’x’, 2), (’y’, 3)]) >>> p._replace(x=77) Point(x=77, y=3) >>> p._fields (’x’, ’y’)
  • 25. namedtuple >>> Point = namedtuple(’Point’, [’x’, ’y’]) >>> p = Point(2, 3) >>> print p.x, p.y 2 3 >>> print p[0:2] (2, 3) >>> print p.count(2) # herda metodos de tuple 1 >>> Point._make([1,2]) Point(x=1, y=2) >>> p._asdict() OrderedDict([(’x’, 2), (’y’, 3)]) >>> p._replace(x=77) Point(x=77, y=3) >>> p._fields (’x’, ’y’)
  • 26. namedtuple >>> Point = namedtuple(’Point’, [’x’, ’y’]) >>> p = Point(2, 3) >>> print p.x, p.y 2 3 >>> print p[0:2] (2, 3) >>> print p.count(2) # herda metodos de tuple 1 >>> Point._make([1,2]) Point(x=1, y=2) >>> p._asdict() OrderedDict([(’x’, 2), (’y’, 3)]) >>> p._replace(x=77) Point(x=77, y=3) >>> p._fields (’x’, ’y’)
  • 27. namedtuple >>> Point = namedtuple(’Point’, [’x’, ’y’]) >>> p = Point(2, 3) >>> print p.x, p.y 2 3 >>> print p[0:2] (2, 3) >>> print p.count(2) # herda metodos de tuple 1 >>> Point._make([1,2]) Point(x=1, y=2) >>> p._asdict() OrderedDict([(’x’, 2), (’y’, 3)]) >>> p._replace(x=77) Point(x=77, y=3) >>> p._fields (’x’, ’y’)
  • 29. OrderedDict >>> d = {’banana’: 3, ’apple’:4, ’pear’: 1, ’orange’: 2} >>> print d {’orange’: 2, ’pear’: 1, ’banana’: 3, ’apple’: 4} >>> print OrderedDict(sorted(d.items())) OrderedDict([(’apple’, 4), (’banana’, 3), (’orange’, 2), (’pear’, 1)]) >>> od = OrderedDict(sorted(d.items(), key=lambda k: k[1])) >>> print od OrderedDict([(’pear’, 1), (’orange’, 2), (’banana’, 3), (’apple’, 4)]) >>> od.popitem() (’apple’, 4) >>> print od OrderedDict([(’pear’, 1), (’orange’, 2), (’banana’, 3)])
  • 30. OrderedDict >>> d = {’banana’: 3, ’apple’:4, ’pear’: 1, ’orange’: 2} >>> print d {’orange’: 2, ’pear’: 1, ’banana’: 3, ’apple’: 4} >>> print OrderedDict(sorted(d.items())) OrderedDict([(’apple’, 4), (’banana’, 3), (’orange’, 2), (’pear’, 1)]) >>> od = OrderedDict(sorted(d.items(), key=lambda k: k[1])) >>> print od OrderedDict([(’pear’, 1), (’orange’, 2), (’banana’, 3), (’apple’, 4)]) >>> od.popitem() (’apple’, 4) >>> print od OrderedDict([(’pear’, 1), (’orange’, 2), (’banana’, 3)])
  • 31. OrderedDict >>> d = {’banana’: 3, ’apple’:4, ’pear’: 1, ’orange’: 2} >>> print d {’orange’: 2, ’pear’: 1, ’banana’: 3, ’apple’: 4} >>> print OrderedDict(sorted(d.items())) OrderedDict([(’apple’, 4), (’banana’, 3), (’orange’, 2), (’pear’, 1)]) >>> od = OrderedDict(sorted(d.items(), key=lambda k: k[1])) >>> print od OrderedDict([(’pear’, 1), (’orange’, 2), (’banana’, 3), (’apple’, 4)]) >>> od.popitem() (’apple’, 4) >>> print od OrderedDict([(’pear’, 1), (’orange’, 2), (’banana’, 3)])
  • 32. OrderedDict >>> d = {’banana’: 3, ’apple’:4, ’pear’: 1, ’orange’: 2} >>> print d {’orange’: 2, ’pear’: 1, ’banana’: 3, ’apple’: 4} >>> print OrderedDict(sorted(d.items())) OrderedDict([(’apple’, 4), (’banana’, 3), (’orange’, 2), (’pear’, 1)]) >>> od = OrderedDict(sorted(d.items(), key=lambda k: k[1])) >>> print od OrderedDict([(’pear’, 1), (’orange’, 2), (’banana’, 3), (’apple’, 4)]) >>> od.popitem() (’apple’, 4) >>> print od OrderedDict([(’pear’, 1), (’orange’, 2), (’banana’, 3)])
  • 33. collections.abc ABC - Abstract Base Class
  • 34. abc em 2 minutos class AbstractKnight(object): __metaclass__ = abc.ABCMeta @abc.abstractmethod def echo(self): pass class IncompKnight(AbstractKnight): pass >>> IncompKnight() TypeError: Can’t instantiate abstract class IncompKnight with abstract methods echo >>> AbstractKnight.__abstractmethods__ frozenset([’echo’]) class KnightImp(AbstractKnight): def echo(self): print ’Ni’ >>> KnightImp().echo() Ni
  • 35. abc em 2 minutos class AbstractKnight(object): __metaclass__ = abc.ABCMeta @abc.abstractmethod def echo(self): pass class IncompKnight(AbstractKnight): pass >>> IncompKnight() TypeError: Can’t instantiate abstract class IncompKnight with abstract methods echo >>> AbstractKnight.__abstractmethods__ frozenset([’echo’]) class KnightImp(AbstractKnight): def echo(self): print ’Ni’ >>> KnightImp().echo() Ni
  • 36. abc em 2 minutos class AbstractKnight(object): __metaclass__ = abc.ABCMeta @abc.abstractmethod def echo(self): pass class IncompKnight(AbstractKnight): pass >>> IncompKnight() TypeError: Can’t instantiate abstract class IncompKnight with abstract methods echo >>> AbstractKnight.__abstractmethods__ frozenset([’echo’]) class KnightImp(AbstractKnight): def echo(self): print ’Ni’ >>> KnightImp().echo() Ni
  • 37. abc em 2 minutos class AbstractKnight(object): __metaclass__ = abc.ABCMeta @abc.abstractmethod def echo(self): pass class IncompKnight(AbstractKnight): pass >>> IncompKnight() TypeError: Can’t instantiate abstract class IncompKnight with abstract methods echo >>> AbstractKnight.__abstractmethods__ frozenset([’echo’]) class KnightImp(AbstractKnight): def echo(self): print ’Ni’ >>> KnightImp().echo() Ni
  • 38. abc em 2 minutos class AbstractKnight(object): __metaclass__ = abc.ABCMeta @abc.abstractmethod def echo(self): pass class IncompKnight(AbstractKnight): pass >>> IncompKnight() TypeError: Can’t instantiate abstract class IncompKnight with abstract methods echo >>> AbstractKnight.__abstractmethods__ frozenset([’echo’]) class KnightImp(AbstractKnight): def echo(self): print ’Ni’ >>> KnightImp().echo() Ni
  • 39. Herdando dict class Dicto(dict): def __getitem__(self, k): return 31 >>> d = Dicto() >>> d[2] 31 >>> print d.get(2) None D’oh : (
  • 40. Herdando dict class Dicto(dict): def __getitem__(self, k): return 31 >>> d = Dicto() >>> d[2] 31 >>> print d.get(2) None D’oh : (
  • 41. Herdando dict class Dicto(dict): def __getitem__(self, k): return 31 >>> d = Dicto() >>> d[2] 31 >>> print d.get(2) None D’oh : (
  • 42. collections.abc • subclasses de builtin containers nem sempre produzem resultados esperados • subclasses de ABC produzem
  • 44. if you’re lazy Callable -> [’__call__’] Container -> [’__contains__’] Hashable -> [’__hash__’] ItemsView -> [] Iterable -> [’__iter__’] # ex: MutableMapping.__abstractmethods__ Iterator -> [’next’] for i in dir(collections): KeysView -> [] try: Mapping -> [’__iter__’, ’__getitem__’, ’__len__’] meths = list(getattr(collections, i MappingView -> [] ).__abstractmethods__) MutableMapping -> [’__delitem__’, ’__setitem__’, print i, ’->’, meths ’__getitem__’, ’__iter__’, ’__len__’] except: MutableSequence -> [’__delitem__’, ’__setitem__’, pass ’__getitem__’, ’__len__’, ’insert’] MutableSet -> [’discard’, ’add’, ’__iter__’, ’__len__’, ’__contains__’] Sequence -> [’__getitem__’, ’__len__’] Set -> [’__iter__’, ’__len__’, ’__contains__’] Sized -> [’__len__’] ValuesView -> []
  • 45. Subclassing dict de collections.MutableMapping from collections import MutableMapping class Dicto(MutableMapping): def __init__(self): self.d = {} >>> d = Dicto() >>> d[’eggs’] = ’ovos’ def __delitem__(self, i): >>> d[’ham’] = ’presunto’ del self.d[i] >>> for i in d: ... print i + ’:’ + d[i] def __setitem__(self, k, v): eggs:ovos self.d[k.lower()] = v ham:presunto >>> d.get(’HaM’) def __getitem__(self, k): presunto return self.d[k.lower()] >>> d[’eGGs’] ’ovos’ def __iter__(self): return iter(self.d) def __len__(self): return len(self.d)
  • 46. Subclassing dict de collections.MutableMapping from collections import MutableMapping class Dicto(MutableMapping): def __init__(self): self.d = {} >>> d = Dicto() >>> d[’eggs’] = ’ovos’ def __delitem__(self, i): >>> d[’ham’] = ’presunto’ del self.d[i] >>> for i in d: ... print i + ’:’ + d[i] def __setitem__(self, k, v): eggs:ovos self.d[k.lower()] = v ham:presunto >>> d.get(’HaM’) def __getitem__(self, k): presunto return self.d[k.lower()] >>> d[’eGGs’] ’ovos’ def __iter__(self): return iter(self.d) def __len__(self): return len(self.d)
  • 47. Referência • Lightning Talk de: no fisl 2011. • The Data Structures of Python, Alex Gaynor no PyCon2011 • http://www.doughellmann.com/PyMOTW/abc/index.html • http://docs.python.org/library/collections.html
  • 48. Dúvidas? André Ericson http://www.github.com/aericson de.ericson@gmail.com @_aericson