Python Language
Módulo de colecciones
Buscar..
Introducción
El paquete de collections
incorporado proporciona varios tipos de colección flexibles y especializados que tienen un alto rendimiento y ofrecen alternativas a los tipos de colección generales de dict
, list
, tuple
y set
. El módulo también define clases básicas abstractas que describen diferentes tipos de funcionalidad de colección (como MutableSet
y ItemsView
).
Observaciones
Hay otros tres tipos disponibles en el módulo de colecciones , a saber:
- UserDict
- Lista de usuarios
- UserString
Cada una de ellas actúa como una envoltura alrededor del objeto atado, por ejemplo, UserDict actúa como una envoltura alrededor de un objeto dict . En cada caso, la clase simula su tipo nombrado. El contenido de la instancia se mantiene en un objeto de tipo regular, al que se puede acceder a través del atributo de datos de la instancia de contenedor. En cada uno de estos tres casos, la necesidad de estos tipos ha sido parcialmente suplantada por la capacidad de subclasificar directamente del tipo básico; sin embargo, puede ser más fácil trabajar con la clase contenedora porque el tipo subyacente es accesible como un atributo.
colecciones.
Contador es una subclase de dict que le permite contar objetos fácilmente. Tiene métodos de utilidad para trabajar con las frecuencias de los objetos que está contando.
import collections
counts = collections.Counter([1,2,3])
el código anterior crea un objeto, cuenta, que tiene las frecuencias de todos los elementos pasados al constructor. Este ejemplo tiene el valor Counter({1: 1, 2: 1, 3: 1})
Ejemplos de constructor
Contador de cartas
>>> collections.Counter('Happy Birthday')
Counter({'a': 2, 'p': 2, 'y': 2, 'i': 1, 'r': 1, 'B': 1, ' ': 1, 'H': 1, 'd': 1, 'h': 1, 't': 1})
Contador de palabras
>>> collections.Counter('I am Sam Sam I am That Sam-I-am That Sam-I-am! I do not like that Sam-I-am'.split())
Counter({'I': 3, 'Sam': 2, 'Sam-I-am': 2, 'That': 2, 'am': 2, 'do': 1, 'Sam-I-am!': 1, 'that': 1, 'not': 1, 'like': 1})
Recetas
>>> c = collections.Counter({'a': 4, 'b': 2, 'c': -2, 'd': 0})
Consigue la cuenta del elemento individual.
>>> c['a']
4
Establecer la cuenta del elemento individual
>>> c['c'] = -3
>>> c
Counter({'a': 4, 'b': 2, 'd': 0, 'c': -3})
Obtener el número total de elementos en el contador (4 + 2 + 0 - 3)
>>> sum(c.itervalues()) # negative numbers are counted!
3
Obtener elementos (solo se mantienen los que tienen un contador positivo)
>>> list(c.elements())
['a', 'a', 'a', 'a', 'b', 'b']
Eliminar claves con 0 o valor negativo.
>>> c - collections.Counter()
Counter({'a': 4, 'b': 2})
Quitar todo
>>> c.clear()
>>> c
Counter()
Añadir eliminar elementos individuales
>>> c.update({'a': 3, 'b':3})
>>> c.update({'a': 2, 'c':2}) # adds to existing, sets if they don't exist
>>> c
Counter({'a': 5, 'b': 3, 'c': 2})
>>> c.subtract({'a': 3, 'b': 3, 'c': 3}) # subtracts (negative values are allowed)
>>> c
Counter({'a': 2, 'b': 0, 'c': -1})
colecciones.defaultdict
collections.defaultdict (default_factory) devuelve una subclase de dict
que tiene un valor predeterminado para las claves que faltan. El argumento debe ser una función que devuelve el valor predeterminado cuando se llama sin argumentos. Si no se pasa nada, el valor predeterminado es None
.
>>> state_capitals = collections.defaultdict(str)
>>> state_capitals
defaultdict(<class 'str'>, {})
devuelve una referencia a un defaultdict que creará un objeto de cadena con su método default_factory.
Un uso típico de defaultdict
es usar uno de los tipos incorporados como str
, int
, list
o dict
como default_factory, ya que estos devuelven tipos vacíos cuando se les llama sin argumentos:
>>> str()
''
>>> int()
0
>>> list
[]
Llamar al valor predeterminado con una clave que no existe no produce un error como lo haría en un diccionario normal.
>>> state_capitals['Alaska']
''
>>> state_capitals
defaultdict(<class 'str'>, {'Alaska': ''})
Otro ejemplo con int
:
>>> fruit_counts = defaultdict(int)
>>> fruit_counts['apple'] += 2 # No errors should occur
>>> fruit_counts
default_dict(int, {'apple': 2})
>>> fruit_counts['banana'] # No errors should occur
0
>>> fruit_counts # A new key is created
default_dict(int, {'apple': 2, 'banana': 0})
Los métodos de diccionario normales funcionan con el diccionario predeterminado
>>> state_capitals['Alabama'] = 'Montgomery'
>>> state_capitals
defaultdict(<class 'str'>, {'Alabama': 'Montgomery', 'Alaska': ''})
El uso de list
como default_factory creará una lista para cada nueva clave.
>>> s = [('NC', 'Raleigh'), ('VA', 'Richmond'), ('WA', 'Seattle'), ('NC', 'Asheville')]
>>> dd = collections.defaultdict(list)
>>> for k, v in s:
... dd[k].append(v)
>>> dd
defaultdict(<class 'list'>,
{'VA': ['Richmond'],
'NC': ['Raleigh', 'Asheville'],
'WA': ['Seattle']})
colecciones.OrdenedDict
El orden de las claves en los diccionarios de Python es arbitrario: no se rigen por el orden en el que se agregan.
Por ejemplo:
>>> d = {'foo': 5, 'bar': 6}
>>> print(d)
{'foo': 5, 'bar': 6}
>>> d['baz'] = 7
>>> print(a)
{'baz': 7, 'foo': 5, 'bar': 6}
>>> d['foobar'] = 8
>>> print(a)
{'baz': 7, 'foo': 5, 'bar': 6, 'foobar': 8}
```
(El orden arbitrario implícito arriba significa que puede obtener resultados diferentes con el código anterior al que se muestra aquí).
El orden en que aparecen las teclas es el orden en el que se iterarían, por ejemplo, utilizando un bucle for
.
La clase collections.OrderedDict
proporciona objetos de diccionario que conservan el orden de las claves. OrderedDict
s se puede crear como se muestra a continuación con una serie de artículos ordenados (aquí, una lista de pares clave-valor de tupla):
>>> from collections import OrderedDict
>>> d = OrderedDict([('foo', 5), ('bar', 6)])
>>> print(d)
OrderedDict([('foo', 5), ('bar', 6)])
>>> d['baz'] = 7
>>> print(d)
OrderedDict([('foo', 5), ('bar', 6), ('baz', 7)])
>>> d['foobar'] = 8
>>> print(d)
OrderedDict([('foo', 5), ('bar', 6), ('baz', 7), ('foobar', 8)])
O podemos crear un OrderedDict
vacío y luego agregar elementos:
>>> o = OrderedDict()
>>> o['key1'] = "value1"
>>> o['key2'] = "value2"
>>> print(o)
OrderedDict([('key1', 'value1'), ('key2', 'value2')])
La OrderedDict
través de un OrderedDict
permite el acceso de claves en el orden en que se agregaron.
¿Qué sucede si asignamos un nuevo valor a una clave existente?
>>> d['foo'] = 4
>>> print(d)
OrderedDict([('foo', 4), ('bar', 6), ('baz', 7), ('foobar', 8)])
La clave conserva su lugar original en el OrderedDict
.
colecciones.namedu tupla
Defina un nuevo tipo de Person
usando namedtuple
como este:
Person = namedtuple('Person', ['age', 'height', 'name'])
El segundo argumento es la lista de atributos que tendrá la tupla. También puede enumerar estos atributos como espacios o cadenas separadas por comas:
Person = namedtuple('Person', 'age, height, name')
o
Person = namedtuple('Person', 'age height name')
Una vez definido, se puede crear una instancia de una tupla con nombre llamando al objeto con los parámetros necesarios, por ejemplo:
dave = Person(30, 178, 'Dave')
Los argumentos con nombre también se pueden utilizar:
jack = Person(age=30, height=178, name='Jack S.')
Ahora puedes acceder a los atributos de la pareja nombrada:
print(jack.age) # 30
print(jack.name) # 'Jack S.'
El primer argumento para el constructor de elementos nombrados (en nuestro ejemplo 'Person'
) es el typename
. Es típico usar la misma palabra para el constructor y el nombre tipográfico, pero pueden ser diferentes:
Human = namedtuple('Person', 'age, height, name')
dave = Human(30, 178, 'Dave')
print(dave) # yields: Person(age=30, height=178, name='Dave')
colecciones.deque
Devuelve un nuevo objeto deque
inicializado de izquierda a derecha (utilizando append ()) con datos de iterable. Si iterable no está especificado, el nuevo deque
está vacío.
Deques es una generalización de pilas y colas (el nombre se pronuncia "deck" y es la abreviatura de "cola doble"). Deques es compatible con subprocesos seguros y eficientes con la memoria y hace estallar desde cualquier lado del deque
con aproximadamente el mismo rendimiento O (1) en cualquier dirección.
Aunque los objetos de la lista admiten operaciones similares, están optimizados para operaciones rápidas de longitud fija e incurren en costos de movimiento de memoria O (n) para operaciones pop (0) e insertar (0, v) que cambian el tamaño y la posición de la representación de datos subyacente .
Nuevo en la versión 2.4.
Si maxlen
no está especificado o es None
, los deques pueden crecer hasta una longitud arbitraria. De lo contrario, el deque
se limita a la longitud máxima especificada. Una vez que el deque
longitud acotada está lleno, cuando se agregan nuevos elementos, un número correspondiente de elementos se descarta del extremo opuesto. Los deques de longitud limitada proporcionan una funcionalidad similar al filtro de cola en Unix. También son útiles para rastrear transacciones y otros grupos de datos donde solo interesa la actividad más reciente.
Cambiado en la versión 2.6: Se agregó el parámetro maxlen.
>>> from collections import deque
>>> d = deque('ghi') # make a new deque with three items
>>> for elem in d: # iterate over the deque's elements
... print elem.upper()
G
H
I
>>> d.append('j') # add a new entry to the right side
>>> d.appendleft('f') # add a new entry to the left side
>>> d # show the representation of the deque
deque(['f', 'g', 'h', 'i', 'j'])
>>> d.pop() # return and remove the rightmost item
'j'
>>> d.popleft() # return and remove the leftmost item
'f'
>>> list(d) # list the contents of the deque
['g', 'h', 'i']
>>> d[0] # peek at leftmost item
'g'
>>> d[-1] # peek at rightmost item
'i'
>>> list(reversed(d)) # list the contents of a deque in reverse
['i', 'h', 'g']
>>> 'h' in d # search the deque
True
>>> d.extend('jkl') # add multiple elements at once
>>> d
deque(['g', 'h', 'i', 'j', 'k', 'l'])
>>> d.rotate(1) # right rotation
>>> d
deque(['l', 'g', 'h', 'i', 'j', 'k'])
>>> d.rotate(-1) # left rotation
>>> d
deque(['g', 'h', 'i', 'j', 'k', 'l'])
>>> deque(reversed(d)) # make a new deque in reverse order
deque(['l', 'k', 'j', 'i', 'h', 'g'])
>>> d.clear() # empty the deque
>>> d.pop() # cannot pop from an empty deque
Traceback (most recent call last):
File "<pyshell#6>", line 1, in -toplevel-
d.pop()
IndexError: pop from an empty deque
>>> d.extendleft('abc') # extendleft() reverses the input order
>>> d
deque(['c', 'b', 'a'])
Fuente: https://docs.python.org/2/library/collections.html
colecciones.ChainMap
ChainMap
es nuevo en la versión 3.3
Devuelve un nuevo objeto ChainMap
dado un número de maps
. Este objeto agrupa varios dicts u otras asignaciones para crear una vista única y actualizable.
ChainMap
son útiles para administrar contextos y superposiciones anidadas. Un ejemplo en el mundo de python se encuentra en la implementación de la clase de Context
en el motor de plantillas de Django. Es útil para vincular rápidamente varias asignaciones para que el resultado se pueda tratar como una sola unidad. A menudo es mucho más rápido que crear un nuevo diccionario y ejecutar varias llamadas de update()
.
Cada vez que uno tiene una cadena de valores de búsqueda, puede haber un caso para ChainMap
. Un ejemplo incluye tener valores especificados por el usuario y un diccionario de valores predeterminados. Otro ejemplo son los mapas de parámetros POST
y GET
que se encuentran en el uso web, por ejemplo, Django o Flask. Mediante el uso de ChainMap
uno devuelve una vista combinada de dos diccionarios distintos.
La lista de parámetros de maps
se ordena desde la primera búsqueda hasta la última búsqueda. Las búsquedas buscan sucesivamente las asignaciones subyacentes hasta que se encuentra una clave. Por el contrario, las escrituras, actualizaciones y eliminaciones solo funcionan en la primera asignación.
import collections
# define two dictionaries with at least some keys overlapping.
dict1 = {'apple': 1, 'banana': 2}
dict2 = {'coconut': 1, 'date': 1, 'apple': 3}
# create two ChainMaps with different ordering of those dicts.
combined_dict = collections.ChainMap(dict1, dict2)
reverse_ordered_dict = collections.ChainMap(dict2, dict1)
Tenga en cuenta el impacto del orden en el que el valor se encuentra primero en la búsqueda posterior
for k, v in combined_dict.items():
print(k, v)
date 1
apple 1
banana 2
coconut 1
for k, v in reverse_ordered_dict.items():
print(k, v)
date 1
apple 3
banana 2
coconut 1