{"id":3933,"library":"collections-extended","title":"Extra Python Collections - bags (multisets) and setlists (ordered sets)","description":"collections_extended is a pure Python module with no dependencies providing various extended collection types. It includes a bag (multiset) class, a setlist (ordered set / unique list) class, a bijection, a RangeMap, and an IndexedDict. It also offers frozen (hashable) variants of bags and setlists. The current version, 2.0.2, maintains an active development status with regular updates and is compatible with Python 3.7+.","status":"active","version":"2.0.2","language":"en","source_language":"en","source_url":"https://github.com/mlenzen/collections-extended","tags":["collections","multiset","bag","ordered set","unique list","indexed dictionary","range map","bijection"],"install":[{"cmd":"pip install collections-extended","lang":"bash","label":"Install with pip"}],"dependencies":[{"reason":"Required Python version compatibility.","package":"python","optional":false}],"imports":[{"symbol":"bag","correct":"from collections_extended import bag"},{"symbol":"setlist","correct":"from collections_extended import setlist"},{"symbol":"IndexedDict","correct":"from collections_extended import IndexedDict"},{"symbol":"RangeMap","correct":"from collections_extended import RangeMap"},{"symbol":"bijection","correct":"from collections_extended import bijection"},{"symbol":"frozenbag","correct":"from collections_extended import frozenbag"},{"symbol":"frozensetlist","correct":"from collections_extended import frozensetlist"}],"quickstart":{"code":"from collections_extended import bag, setlist, IndexedDict, RangeMap\nfrom datetime import date\n\n# Example with bag (multiset)\nb = bag('abracadabra')\nprint(f\"Bag: {b}, Count of 'a': {b.count('a')}\")\nb.remove('a')\nprint(f\"Bag after removing 'a': {b}, Count of 'a': {b.count('a')}\")\n\n# Example with setlist (ordered set)\nsl = setlist('abracadabra')\nprint(f\"Setlist: {sl}, element at index 3: {sl[3]}\")\ntry:\n    sl.insert(1, 'd')\nexcept ValueError as e:\n    print(f\"Attempted to insert duplicate into setlist: {e}\")\n\n# Example with IndexedDict\nidict = IndexedDict({'a': 1, 'b': 2, 'c': 3})\nprint(f\"IndexedDict: {idict}, value at index 1: {idict.iloc[1]}\")\n\n# Example with RangeMap\nversion_map = RangeMap()\nversion_map[date(2017, 10, 20): date(2017, 10, 27)] = '0.10.1'\nversion_map[date(2017, 10, 27):] = '1.0.0'\nprint(f\"Version for 2017-10-24: {version_map[date(2017, 10, 24)]}\")","lang":"python","description":"Demonstrates basic usage of `bag`, `setlist`, `IndexedDict`, and `RangeMap` from `collections-extended`."},"warnings":[{"fix":"Upgrade Python to 3.7+ or pin collections-extended to a 1.x version if Python 2.7/3.4/3.5 support is required.","message":"Version 2.0.0 dropped support for Python 2.7, 3.4, and 3.5. Ensure your environment is Python 3.6 or later for v2.x.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Review code that uses `bag` multiplication (`*`) and adjust logic if the previous 'addition' behavior was expected. The new behavior is a cartesian product, yielding tuples.","message":"When multiplying `bag` objects, the behavior changed in v2.0.0. It now produces a cartesian product as a tuple, rather than adding elements.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"If comparing `bag` instances with `set` instances, explicit conversion (e.g., `set(my_bag) == my_set`) or a different comparison logic may be necessary.","message":"As of v2.0.0, `bags` no longer inherit from `Set`, meaning they cannot be compared for equality directly with `Set` objects.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Update any direct imports or references to `_basebag` or `_basesetlist` to use `Bag` or `SetList`.","message":"Internal base classes `_basebag` and `_basesetlist` were renamed to `Bag` and `SetList` respectively and are now exposed in v2.0.0.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Check for element existence (e.g., `if element not in my_setlist: my_setlist.insert(...)`) or handle the `ValueError` if duplicate insertion is attempted.","message":"Calling `setlist.insert(index, element)` will raise a `ValueError` if the `element` is already present in the `setlist`.","severity":"gotcha","affected_versions":"All versions"},{"fix":"If order-sensitive comparison is needed, convert `setlist` to a `list`. For set-based comparison, convert to a `set`.","message":"`setlist` objects are not comparable using ordering operators (`<`, `>`, `<=`, `>=`) due to the ambiguity between set comparison and order-based comparison. Equality (`==`, `!=`) still works.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-11T00:00:00.000Z","next_check":"2026-07-10T00:00:00.000Z"}