Ir al contenido

Collection

Collection es un wrapper fluido sobre listas de Python que proporciona un amplio conjunto de métodos para filtrar, transformar, agregar y paginar datos. En lugar de encadenar funciones integradas o escribir bucles repetitivos, las operaciones sobre datos se expresan de forma legible y declarativa.

Las colecciones aceptan cualquier lista de elementos — escalares, diccionarios, objetos — y exponen una API consistente que cubre las necesidades más comunes de manipulación de datos en el desarrollo de aplicaciones.

from orionis.support.structures.collection import Collection
# Desde una lista
users = Collection([1, 2, 3])
# Colección vacía
empty = Collection()
# None se trata como vacío
also_empty = Collection(None)

Retorna el primer elemento, o None si la colección está vacía. Un callback opcional filtra los elementos antes de seleccionar:

c = Collection([1, 2, 3, 4])
c.first() # 1
c.first(lambda x: x > 2) # 3
c.first(lambda x: x > 10) # None

Retorna el último elemento, con el mismo comportamiento de callback opcional:

c = Collection([1, 2, 3, 4])
c.last() # 4
c.last(lambda x: x < 4) # 3

Obtiene un elemento por índice. Retorna un valor por defecto (None por defecto) cuando el índice está fuera de rango:

c = Collection([10, 20, 30])
c.get(1) # 20
c.get(99) # None
c.get(99, "missing") # "missing"

Retorna uno o más elementos aleatorios. Sin argumentos retorna un valor único; con un conteo retorna una Collection:

c = Collection([1, 2, 3, 4, 5])
c.random() # elemento aleatorio único
c.random(3) # Collection con 3 elementos aleatorios

Retorna None para colecciones vacías. Lanza ValueError si el conteo excede el tamaño de la colección.


Añade un valor al final:

c = Collection([1, 2])
c.push(3)
c.all() # [1, 2, 3]

Inserta un valor al inicio:

c = Collection([2, 3])
c.prepend(1)
c.all() # [1, 2, 3]

Elimina y retorna el último elemento. Retorna None si la colección está vacía:

c = Collection([1, 2, 3])
c.pop() # 3
c.all() # [1, 2]

Elimina y retorna el primer elemento:

c = Collection([10, 20, 30])
c.shift() # 10
c.all() # [20, 30]

Elimina y retorna el elemento en un índice dado:

c = Collection([10, 20, 30])
c.pull(1) # 20
c.all() # [10, 30]

Reemplaza el valor en un índice específico:

c = Collection([1, 2, 3])
c.put(1, 99)
c.all() # [1, 99, 3]

Elimina elementos por uno o más índices:

c = Collection([10, 20, 30, 40])
c.forget(0, 2)
c.all() # [20, 40]

Añade elementos desde una lista u otra Collection. Lanza TypeError para tipos incompatibles:

c = Collection([1, 2])
c.merge([3, 4])
c.all() # [1, 2, 3, 4]

Retorna una nueva colección con los elementos que pasan la prueba:

c = Collection([1, 2, 3, 4, 5])
c.filter(lambda x: x > 3).all() # [4, 5]

El inverso de filter — elimina los elementos que coinciden con el callback. Modifica la colección en su lugar:

c = Collection([1, 2, 3, 4])
c.reject(lambda x: x > 2)
c.all() # [1, 2]

Filtra elementos de diccionario por una condición clave-valor. Soporta operadores de comparación:

items = Collection([{"v": 1}, {"v": 5}, {"v": 10}])
items.where("v", 5).all() # [{"v": 5}]
items.where("v", ">", 3).all() # [{"v": 5}, {"v": 10}]

Operadores soportados: ==, !=, <, <=, >, >=.

Filtra elementos cuyo valor de clave está (o no está) en una lista dada:

c = Collection([{"id": 1}, {"id": 2}, {"id": 3}])
c.whereIn("id", [1, 3]).count() # 2
c.whereNotIn("id", [2]).count() # 2

Retorna una nueva colección sin valores duplicados. Pase una clave para unicidad basada en diccionarios:

Collection([1, 2, 2, 3]).unique().count() # 3
items = Collection([
{"id": 1, "v": "a"},
{"id": 2, "v": "b"},
{"id": 1, "v": "c"},
])
items.unique("id").count() # 2

Verifica si un valor — o un valor que coincida con un callback o par clave-valor — existe en la colección:

c = Collection([1, 2, 3])
c.contains(2) # True
c.contains(99) # False
c.contains(lambda x: x > 2) # True
items = Collection([{"name": "a"}, {"name": "b"}])
items.contains("name", "a") # True

Retorna los elementos que no están presentes en la lista o colección dada:

c = Collection([1, 2, 3, 4])
c.diff([2, 4]).all() # [1, 3]

Aplica un callback a cada elemento y retorna una nueva colección:

c = Collection([1, 2, 3])
c.map(lambda x: x * 10).all() # [10, 20, 30]

Como map, pero modifica la colección en su lugar:

c = Collection([1, 2, 3])
c.transform(lambda x: x * 2)
c.all() # [2, 4, 6]

Itera y aplica un callback a cada elemento en su lugar. Detiene la iteración si el callback retorna un valor falsy:

c = Collection([1, 2, 3])
c.each(lambda x: x * 2)
c.all() # [2, 4, 6]

Crea instancias de una clase dada a partir de cada elemento:

c = Collection([1, 2, 3])
c.mapInto(str).all() # ["1", "2", "3"]

Lanza TypeError si el argumento no es un tipo.

Aplana recursivamente listas anidadas y valores de diccionarios en una colección de un solo nivel:

Collection([1, [2, [3, 4]], 5]).flatten().all()
# [1, 2, 3, 4, 5]
Collection([{"a": 1, "b": 2}]).flatten().all()
# [1, 2]

Fusiona un nivel de listas anidadas en una colección plana:

Collection([[1, 2], [3, 4]]).collapse().all()
# [1, 2, 3, 4]

Invierte el orden de los elementos en su lugar:

c = Collection([1, 2, 3])
c.reverse()
c.all() # [3, 2, 1]

Ordena los elementos en orden ascendente. Pase un nombre de clave para ordenar diccionarios por un campo específico:

c = Collection([3, 1, 2])
c.sort()
c.all() # [1, 2, 3]
items = Collection([{"v": 3}, {"v": 1}, {"v": 2}])
items.sort("v")
items.all() # [{"v": 1}, {"v": 2}, {"v": 3}]

Retorna la cantidad de elementos. También disponible mediante len():

c = Collection([1, 2, 3])
c.count() # 3
len(c) # 3

Calcula el total. Pase una clave para sumar un campo específico de diccionarios:

Collection([1, 2, 3]).sum() # 6
Collection([{"v": 10}, {"v": 20}]).sum("v") # 30

Retorna 0 para colecciones vacías.

Calcula la media aritmética:

Collection([2, 4, 6]).avg() # 4.0
Collection([{"v": 10}, {"v": 20}]).avg("v") # 15.0

Retorna 0 para colecciones vacías.

Retornan el mayor y menor valor respectivamente:

c = Collection([3, 1, 4, 1, 5])
c.max() # 5
c.min() # 1

Ambos retornan 0 para colecciones vacías.

Acumula todos los elementos en un solo valor usando un callback:

c = Collection([1, 2, 3])
c.reduce(lambda acc, x: acc + x, 0) # 6

Retorna True solo si todos los elementos satisfacen el callback:

Collection([2, 4, 6]).every(lambda x: x % 2 == 0) # True
Collection([2, 3, 6]).every(lambda x: x % 2 == 0) # False

Retorna True cuando la colección no tiene elementos:

Collection().isEmpty() # True
Collection([1]).isEmpty() # False

Extrae valores para una clave dada de una colección de diccionarios. Una segunda clave opcional sirve como índice del resultado:

c = Collection([{"n": "a"}, {"n": "b"}, {"n": "c"}])
c.pluck("n").all() # ["a", "b", "c"]
users = Collection([
{"id": 1, "name": "Alice"},
{"id": 2, "name": "Bob"},
])
users.pluck("name", "id").all() # {1: "Alice", 2: "Bob"}

Toma elementos desde el inicio (positivo) o el final (negativo) de la colección:

c = Collection([1, 2, 3, 4, 5])
c.take(3).all() # [1, 2, 3]
c.take(-2).all() # [4, 5]
c.take(0).all() # []

Agrupa elementos por una clave especificada, produciendo una colección cuyos elementos son un diccionario que mapea claves de grupo a listas:

c = Collection([
{"type": "a", "v": 1},
{"type": "b", "v": 2},
{"type": "a", "v": 3},
])
groups = c.groupBy("type")
# {"a": [...], "b": [...]}

Retorna un segmento de elementos para un número de página y tamaño de página dados:

c = Collection([1, 2, 3, 4, 5, 6])
c.forPage(1, 2).all() # [1, 2]
c.forPage(2, 2).all() # [3, 4]
c.forPage(3, 2).all() # [5, 6]

Lanza ValueError si el tamaño de página es cero o negativo.

Divide la colección en colecciones más pequeñas del tamaño dado:

c = Collection([1, 2, 3, 4, 5])
chunks = c.chunk(2)
chunks[0].all() # [1, 2]
chunks[1].all() # [3, 4]
chunks[2].all() # [5]

Lanza ValueError si el tamaño del chunk es cero o negativo.


Retorna una representación como cadena JSON:

Collection([1, 2, 3]).toJson() # "[1, 2, 3]"

Retorna los elementos subyacentes como una lista plana. Para elementos que implementan un método serialize o to_dict, esos métodos se invocan automáticamente:

Collection([1, "a", None]).serialize() # [1, "a", None]

Une todos los elementos en una cadena con un separador (por defecto ,):

Collection(["a", "b", "c"]).implode("-") # "a-b-c"
Collection(["x", "y"]).implode() # "x,y"

Empareja elementos de la colección con elementos de otra lista o colección por índice:

c = Collection([1, 2, 3])
c.zip([4, 5, 6]).all()
# [[1, 4], [2, 5], [3, 6]]

Lanza TypeError si el argumento no es una lista o Collection.


Collection soporta acceso estándar de Python con corchetes, slicing, asignación e iteración:

c = Collection([10, 20, 30])
c[0] # 10
c[1] = 99 # establece el índice 1 a 99
c[0:2] # Collection([10, 99])
for item in c:
print(item)

El slicing retorna una nueva Collection. La función len() retorna la cantidad de elementos.


Las colecciones soportan ==, !=, <, <=, >, >= usando la semántica de comparación estándar de listas:

a = Collection([1, 2, 3])
b = Collection([1, 2, 3])
c = Collection([1, 3])
a == b # True
a < c # True

Las colecciones con elementos idénticos también producen el mismo valor de hash().


MétodoRetornaMutaDescripción
all()listNoRetorna todos los elementos como lista
avg(key?)floatNoMedia aritmética de los elementos o valores de clave
chunk(size)CollectionNoDivide en sub-colecciones del tamaño dado
collapse()CollectionNoAplana un nivel de listas anidadas
contains(key, value?)boolNoVerifica valor, coincidencia de callback o par clave-valor
count()intNoNúmero de elementos
diff(items)CollectionNoElementos que no están en la lista dada
each(callback)CollectionAplica callback en su lugar, se detiene con retorno falsy
every(callback)boolNoTrue si todos pasan la prueba
filter(callback)CollectionNoElementos que pasan la prueba del callback
flatten()CollectionNoAplana recursivamente estructuras anidadas
forPage(page, size)CollectionNoSegmento paginado
forget(*keys)CollectionElimina elementos por índice
first(callback?)objectNoPrimer elemento, opcionalmente filtrado
get(index, default?)objectNoElemento por índice con valor por defecto
groupBy(key)CollectionNoAgrupa elementos por un campo clave
implode(glue?, key?)strNoUne elementos en una cadena
isEmpty()boolNoTrue si la colección no tiene elementos
last(callback?)objectNoÚltimo elemento, opcionalmente filtrado
map(callback)CollectionNoNueva colección con elementos transformados
mapInto(cls)CollectionNoMapea elementos a instancias de clase
max(key?)objectNoValor máximo
merge(items)CollectionAñade elementos desde lista o Collection
min(key?)objectNoValor mínimo
pluck(value, key?)CollectionNoExtrae valores por clave
pop()objectElimina y retorna el último elemento
prepend(value)CollectionInserta elemento al inicio
pull(index)objectElimina y retorna elemento por índice
push(value)CollectionAñade elemento al final
put(index, value)CollectionReemplaza valor en el índice
random(count?)object|CollectionNoElemento(s) aleatorio(s)
reduce(callback, initial)objectNoAcumula a un solo valor
reject(callback)CollectionElimina elementos que coinciden con callback
reverse()CollectionInvierte el orden de los elementos
serialize()listNoElementos como lista serializada
shift()objectElimina y retorna el primer elemento
sort(key?)CollectionOrdena elementos en orden ascendente
sum(key?)floatNoSuma de elementos o valores de clave
take(n)CollectionNoPrimeros n o últimos n elementos
toJson()strNoRepresentación como cadena JSON
transform(callback)CollectionTransforma elementos en su lugar
unique(key?)CollectionNoElimina elementos duplicados
where(key, ...)CollectionNoFiltra por comparación clave-valor
whereIn(key, values)CollectionNoFiltra donde la clave está en los valores
whereNotIn(key, values)CollectionNoFiltra donde la clave no está en los valores
zip(items)CollectionNoEmpareja elementos por índice