Skip to content

Collection

Collection is a fluent wrapper around Python lists that provides a rich set of methods for filtering, transforming, aggregating, and paginating data. Instead of chaining built-in functions or writing repetitive loops, you can express data operations in a readable, declarative style.

Collections accept any list of items — scalars, dictionaries, objects — and expose a consistent API that covers the most common data manipulation needs in application development.

from orionis.support.structures.collection import Collection
# From a list
users = Collection([1, 2, 3])
# Empty collection
empty = Collection()
# None is treated as empty
also_empty = Collection(None)

Returns the first item, or None if the collection is empty. An optional callback filters items before selecting:

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

Returns the last item, with the same optional callback behavior:

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

Retrieves an item by index. Returns a default value (None by default) when the index is out of range:

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

Returns one or more random items. Without arguments returns a single value; with a count returns a Collection:

c = Collection([1, 2, 3, 4, 5])
c.random() # single random item
c.random(3) # Collection with 3 random items

Returns None for empty collections. Raises ValueError if the count exceeds the collection size.


Appends a value to the end:

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

Inserts a value at the beginning:

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

Removes and returns the last item. Returns None if the collection is empty:

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

Removes and returns the first item:

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

Removes and returns the item at a given index:

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

Replaces the value at a specific index:

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

Removes items by one or more indices:

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

Appends items from a list or another Collection. Raises TypeError for incompatible types:

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

Returns a new collection with items that pass a truth test:

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

The inverse of filter — removes items that match the callback. Modifies the collection in place:

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

Filters dictionary items by a key-value condition. Supports comparison operators:

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

Supported operators: ==, !=, <, <=, >, >=.

Filters items whose key value is (or is not) in a given list:

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

Returns a new collection with duplicate values removed. Pass a key for dict-based uniqueness:

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

Checks whether a value — or a value matching a callback or key-value pair — exists in the collection:

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

Returns items not present in the given list or collection:

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

Applies a callback to every item and returns a new collection:

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

Like map, but modifies the collection in place:

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

Iterates and applies a callback to each item in place. Stops iteration if the callback returns a falsy value:

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

Creates instances of a given class from each item:

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

Raises TypeError if the argument is not a type.

Recursively flattens nested lists and dictionary values into a single-level collection:

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

Merges one level of nested lists into a flat collection:

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

Reverses the item order in place:

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

Sorts items in ascending order. Pass a key name to sort dictionaries by a specific field:

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}]

Returns the number of items. Also available via len():

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

Computes the total. Pass a key to sum a specific field from dicts:

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

Returns 0 for empty collections.

Computes the arithmetic mean:

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

Returns 0 for empty collections.

Return the largest and smallest values respectively:

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

Both return 0 for empty collections.

Accumulates all items into a single value using a callback:

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

Returns True only if all items satisfy the callback:

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

Returns True when the collection has no items:

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

Extracts values for a given key from a collection of dictionaries. An optional second key serves as the index for the result:

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"}

Takes items from the beginning (positive) or end (negative) of the collection:

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

Groups items by a specified key, producing a collection whose items are a dictionary mapping group keys to lists:

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

Returns a slice of items for a given page number and page size:

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]

Raises ValueError if the page size is zero or negative.

Splits the collection into smaller collections of the given size:

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]

Raises ValueError if the chunk size is zero or negative.


Returns a JSON string representation:

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

Returns the underlying items as a plain list. For items that implement a serialize or to_dict method, those methods are called automatically:

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

Joins all items into a string with a separator (default ,):

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

Pairs items from the collection with items from another list or collection by index:

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

Raises TypeError if the argument is not a list or Collection.


Collection supports standard Python bracket access, slicing, assignment, and iteration:

c = Collection([10, 20, 30])
c[0] # 10
c[1] = 99 # sets index 1 to 99
c[0:2] # Collection([10, 99])
for item in c:
print(item)

Slicing returns a new Collection. The len() function returns the item count.


Collections support ==, !=, <, <=, >, >= using standard list comparison semantics:

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

Collections with identical items also produce the same hash() value.


MethodReturnsMutatesDescription
all()listNoReturns all items as a plain list
avg(key?)floatNoArithmetic mean of items or key values
chunk(size)CollectionNoSplits into sub-collections of given size
collapse()CollectionNoFlattens one level of nested lists
contains(key, value?)boolNoChecks for value, callback match, or key-value pair
count()intNoNumber of items
diff(items)CollectionNoItems not in the given list
each(callback)CollectionYesApplies callback in place, stops on falsy return
every(callback)boolNoTrue if all items pass the test
filter(callback)CollectionNoItems passing the callback test
flatten()CollectionNoRecursively flattens nested structures
forPage(page, size)CollectionNoPaginated slice
forget(*keys)CollectionYesRemoves items by index
first(callback?)objectNoFirst item, optionally filtered
get(index, default?)objectNoItem by index with default fallback
groupBy(key)CollectionNoGroups items by a key field
implode(glue?, key?)strNoJoins items into a string
isEmpty()boolNoTrue if collection has no items
last(callback?)objectNoLast item, optionally filtered
map(callback)CollectionNoNew collection with transformed items
mapInto(cls)CollectionNoMaps items into class instances
max(key?)objectNoMaximum value
merge(items)CollectionYesAppends items from list or Collection
min(key?)objectNoMinimum value
pluck(value, key?)CollectionNoExtracts values by key
pop()objectYesRemoves and returns the last item
prepend(value)CollectionYesInserts item at the beginning
pull(index)objectYesRemoves and returns item by index
push(value)CollectionYesAppends item to the end
put(index, value)CollectionYesReplaces value at index
random(count?)object|CollectionNoRandom item(s)
reduce(callback, initial)objectNoAccumulates to a single value
reject(callback)CollectionYesRemoves items matching callback
reverse()CollectionYesReverses item order
serialize()listNoItems as a plain serialized list
shift()objectYesRemoves and returns the first item
sort(key?)CollectionYesSorts items in ascending order
sum(key?)floatNoSum of items or key values
take(n)CollectionNoFirst n or last n items
toJson()strNoJSON string representation
transform(callback)CollectionYesTransforms items in place
unique(key?)CollectionNoRemoves duplicate items
where(key, ...)CollectionNoFilters by key-value comparison
whereIn(key, values)CollectionNoFilters where key is in values
whereNotIn(key, values)CollectionNoFilters where key is not in values
zip(items)CollectionNoPairs items by index