mrkeyoor.com_
Mon 21 Sept 21:54 UTC
PyPIUtilsupdated 21 Sept 2026

ordered-set review

ordered-set 4.1.0 supplies one Python collection, `OrderedSet`, that combines unique membership with insertion order and integer positions. A list stores values while a dictionary maps each value to its index, making membership, item-to-index lookup, and index-to-item lookup constant time. It also implements mutable-set operators, sequence slicing, NumPy-style lists of indices, and aliases used by `pandas.Index`. Version 4.1 moved the code into a package, added wheels and a `py.typed` marker, adopted Flit packaging, and raised the Python floor to 3.7.

Verdict

ordered-set earns its dependency for token-to-ID tables and other append-heavy collections that need lookup in both directions. For order-preserving deduplication alone, a built-in dictionary is simpler and removes the release-cadence concern.

We installed it

Lab card: what happened when we installed ordered-setScreenshot of ordered-set documentation
Install✓ · 0.2s1 package on disk · 1 MB
Importimport ordered_set in 0.08s · pure Python · py.typed · requires Python >=3.7
Known vulns0(pip-audit)

Answers from our run

Does ordered-set install cleanly?

Yes. In a fresh container with an empty cache, pip install ordered-set finished in 0.2s, leaving 1 package and 1 MB on disk. pip-audit reported no known vulnerabilities.

What does ordered-set need to run?

Python >=3.7, and nothing compiled: it is pure Python. In our run import ordered_set succeeded in 0.08s, and the package ships py.typed for type checkers.

ordered-set or orderly-set: which should you use?

orderly-set: Use it when you want a currently released ordered-set package with a newer Python support range. ordered-set earns its dependency for token-to-ID tables and other append-heavy collections that need lookup in both directions.

When should you not use ordered-set?

You only need first-seen deduplication. list(dict.fromkeys(items)) uses the standard library and avoids another package.

API stability5/5The published interface has stayed on version 4.1.0 since January 2022, and its central methods follow Python's `MutableSet` and `Sequence` contracts. `add` returning an index, fancy indexing, pandas-style aliases, slices, and set operators are all documented behavior. That long quiet period lowers upgrade churn, though it also means post-release typing changes on the repository have not reached PyPI and should not be treated as part of the installed API.
Docs3/5The README explains the list-plus-dictionary design, its O(1) lookups and O(n) deletion tradeoff, set operators, fancy indexing, pandas aliases, generic typing, and the built-in dictionary comparison. A short changelog identifies every major and minor change through 4.1. There is no separate API site or detailed exception reference, so callers must inspect docstrings or code for corners such as missing-item errors, equality dispatch, update return values, and slice result types.
Maintenance2/5PyPI 4.1.0 was uploaded on 2022-01-26. GitHub shows a last push on 2024-08-09, 230 stars, 17 open issues and pull requests, and an unarchived repository. Later commits adjust covariance and formatting, but no newer distribution contains them. The pure Python implementation is small and our Python 3.12 import worked, yet organizations that require regular releases or stated support for recent interpreters have little current evidence to rely on.
Ecosystem3/5The supplied weekly figure is 8,518,894 downloads, and the wheel is pure Python with inline generic types plus a `py.typed` marker. Compatibility aliases for `pandas.Index` and acceptance of NumPy index arrays make it useful in data pipelines without importing pandas for a small operation. It remains a single-class package with no extension system, storage adapters, or tooling, and most simple deduplication tasks are already covered by insertion-ordered dictionaries.

Use it if

  • A vocabulary builder needs `add(token)` to return a stable dense ID while duplicates reuse their existing ID.
  • One value must support insertion-ordered iteration, membership checks, set algebra, slicing, and reverse lookup by position.
  • NumPy arrays or lists of positions should select several unique values without pulling in pandas.
  • Items are added far more often than removed, so constant-time index lookup matters more than cheap deletion.
Skip it if

Setup reality

We installed ordered-set 4.1.0 in a fresh unprivileged Python 3.12 Bookworm container with no cache. Installation finished in 0.2 seconds and left one package using 1 MB. Our package inspection counted 3 direct dependencies. The distribution is pure Python, requires Python 3.7 or newer, ships py.typed, and uses the MIT License. pip-audit found zero known vulnerabilities.

The distribution name contains a hyphen, but code imports OrderedSet from ordered_set. import ordered_set succeeded in 0.08 seconds in our sandbox. No compiler, credentials, service, or configuration file is involved. PyPI has a universal wheel, so the practical compatibility question is behavior on newer interpreters rather than native binary availability.

Internally, positions belong to a list and membership belongs to a dictionary. Adding an existing value returns its current position; adding a new one appends it. Deletion must remove from the list and adjust later positions, which costs O(n). Do not persist those positions as external IDs if the set can shrink. Values must also be hashable, and the mutable OrderedSet itself cannot be used as a dictionary key or nested inside another set.

Slicing returns another OrderedSet, while passing an iterable of indices returns a plain list and may repeat positions. The same index method accepts either one item or several items, so error and return types vary with the argument. Version 4.1 is still the latest PyPI release even though the repository received type-related commits in 2024. Pin 4.1.0, test it on your supported Python versions, and do not assume unreleased repository changes are installed.

Patterns

Keep the first occurrence of each item dedupe-preserving-order

from ordered_set import OrderedSet

rows = ['b', 'a', 'b', 'c', 'a']
unique = OrderedSet(rows)
assert list(unique) == ['b', 'a', 'c']

If the result only needs to be a list, `list(dict.fromkeys(rows))` does the same job without this dependency.

Move between values and positions lookup-both-directions

from ordered_set import OrderedSet

letters = OrderedSet('abracadabra')
assert letters.index('r') == 2
assert letters[2] == 'r'
assert 'r' in letters

Both lookups are constant time while the set is unchanged. Deletion shifts later positions.

Assign dense IDs while inserting intern-values

from ordered_set import OrderedSet

vocab = OrderedSet()
ids = [vocab.add(word) for word in ['the', 'cat', 'the', 'sat']]
assert ids == [0, 1, 0, 2]

`add` returns the existing index for a duplicate and the appended index for a new value.

Append unseen values from an iterable bulk-update

from ordered_set import OrderedSet

items = OrderedSet([1, 2, 3])
last_index = items.update([3, 5, 4])
assert items == [1, 2, 3, 5, 4]
assert last_index == 4

`update` returns the position of the final value it processed, not the number of additions.

Select several positions fancy-indexing

import numpy as np
from ordered_set import OrderedSet

letters = OrderedSet('abracadabra')
assert letters[[0, 2, 3]] == ['a', 'r', 'c']
assert letters[np.array([1, 1])] == ['b', 'b']

Iterable indexing returns a list because requested positions may repeat. A slice returns an `OrderedSet` instead.

Resolve several values to positions lookup-many-indices

from ordered_set import OrderedSet

letters = OrderedSet('abracadabra')
positions = letters.index(['a', 'r', 'c'])
assert positions == [0, 2, 3]

A missing member raises during the lookup. Validate external values first if partial results are useful.

Apply set algebra without losing left order set-operations

from ordered_set import OrderedSet

left = OrderedSet(['a', 'b', 'c'])
assert left | ['c', 'd'] == ['a', 'b', 'c', 'd']
assert left & {'a', 'c'} == ['a', 'c']
assert left - {'b'} == ['a', 'c']

A string on the right is treated as an iterable of characters, which can be surprising for multi-character values.

Choose strict or forgiving removal remove-items

from ordered_set import OrderedSet

items = OrderedSet(['a', 'b', 'c'])
items.discard('missing')
items.remove('b')
last = items.pop()

`remove` raises for an absent item, `discard` does not, and each successful middle deletion reindexes later values.

Slice and reverse the sequence view slice-and-reverse

from ordered_set import OrderedSet

items = OrderedSet('abcdef')
subset = items[1:4]
backwards = list(reversed(items))
assert subset == ['b', 'c', 'd']
assert backwards[0] == 'f'

A slice produces a shallow `OrderedSet`; mutable objects inside it are shared with the original.

Use pandas-compatible lookup names pandas-style-lookup

from ordered_set import OrderedSet

vocab = OrderedSet(['red', 'green', 'blue'])
assert vocab.get_loc('green') == 1
assert vocab.get_indexer(['blue', 'red']) == [2, 0]

These methods are aliases for `index`; they do not reproduce the rest of the pandas Index API.

Test order-aware equality explicitly check-equality

from ordered_set import OrderedSet

items = OrderedSet([1, 2, 3])
assert items == [1, 2, 3]
assert items != [3, 2, 1]
assert items == {3, 2, 1}

Sequence comparison checks order, while comparison with a plain set checks membership only.

Serialize and restore an ordered set pickle-collection

import pickle
from ordered_set import OrderedSet

original = OrderedSet(['alpha', 'beta'])
payload = pickle.dumps(original)
restored = pickle.loads(payload)
assert restored == original

Only unpickle data from a trusted source; Python pickle can execute code during loading.

Alternatives

PackageRegistryPick it when
orderly-setPyPIUse it when you want a currently released ordered-set package with a newer Python support range.
sortedcontainersPyPIUse `SortedSet` when values should follow sort order and removals need logarithmic behavior.
boltonsPyPIUse `IndexedSet` when indexed uniqueness is one of several utility needs and deletion patterns are less append-heavy.

More utils guides

lru-cache · ajv · type-fest · p-limit · find-up · js-yaml · the whole shelf →

How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.