Skip to main content

Small helpers for list managment

Project description

btx_lib_list

CI CodeQL License: MIT Open in Codespaces PyPI PyPI - Downloads Code Style: Ruff codecov Maintainability Known Vulnerabilities

  • small list helpers

Install

pip install btx_lib_list

For alternative install paths (pipx, uv, source builds, etc.), see INSTALL.md. All supported methods register both the btx_lib_list and btx-lib-list commands on your PATH.

Python 3.13+ Baseline

  • The project now targets Python 3.13 and newer only. All compatibility shims for older interpreters and legacy tool outputs have been removed; the automation helpers now lean on modern conveniences such as Path.unlink(missing_ok=True) and standard-library shutil.which() lookups.
  • Runtime dependencies stay on the current stable releases (rich-click>=1.9.3 and lib_cli_exit_tools>=2.0.0), while the development extra trims unused packages (notably pytest-asyncio) and keeps pytest, ruff, pyright, bandit, build, twine, codecov-cli, pip-audit, textual, and import-linter pinned to their newest majors.
  • CI workflows now exercise GitHub's rolling runner images (ubuntu-latest, macos-latest, windows-latest) and cover CPython 3.13 alongside the latest available 3.x release provided by Actions.

Usage

The CLI leverages rich-click so help output, validation errors, and prompts render with Rich styling while keeping the familiar click ergonomics. The scaffold keeps a CLI entry point so you can validate packaging flows, but it currently exposes a single informational command while logging features are developed:

btx_lib_list info
btx_lib_list hello
btx_lib_list fail
btx_lib_list --traceback fail
btx-lib-list info
python -m btx_lib_list info

For library use you can import the documented helpers directly:

import btx_lib_list

btx_lib_list.emit_greeting()
try:
    btx_lib_list.raise_intentional_failure()
except RuntimeError as exc:
    print(f"caught expected failure: {exc}")

btx_lib_list.print_info()

Development Quickstart

These steps assume Python 3.13+ (the same baseline enforced by pyproject.toml).

make dev           # install the project in editable mode with dev extras
make test          # run linting, type checks, docs/doctests, and pytest
python -m pytest   # thanks to pytest's configured pythonpath, this now works without extra env vars

The CLI fixtures exercise the lib_list helpers directly, so any changes to the legacy compatibility layer should be accompanied by matching updates in tests/test_lib_list.py.

Public API

The helpers are available directly off the package root (btx_lib_list.<function_name>). The summaries below describe the behaviour and intended use of each helper.

btx_lib_list.deduplicate(elements: list[Any]) -> list[Any]

Removes duplicate, hashable values from elements without preserving order. Used when older CLI flows accidentally emit repeat arguments.

Docs: Module Reference

Example:

>>> from btx_lib_list import deduplicate
>>> deduplicate([])
[]
>>> sorted(deduplicate(['c', 'b', 'a']))
['a', 'b', 'c']
>>> sorted(deduplicate(['b', 'a', 'c', 'b', 'a']))
['a', 'b', 'c']
>>> sorted(deduplicate(['x', 'x', 'x', 'y', 'y']))
['x', 'y']

btx_lib_list.del_elements_containing(elements: list[str], search_string: str) -> list[str]

Returns a new list that excludes any string containing search_string. Handy for pruning blacklisted patterns before issuing filesystem calls.

Docs: Module Reference

Example:

>>> from btx_lib_list import del_elements_containing
>>> del_elements_containing(['a', 'abba', 'c'], 'b')
['a', 'c']
>>> del_elements_containing(['a', 'abba', 'c'], 'z')
['a', 'abba', 'c']
>>> del_elements_containing(['a', 'abba', 'c'], '')
['a', 'abba', 'c']
>>> del_elements_containing([], 'b')
[]

btx_lib_list.filter_contains(elements: list[Any], search_string: str) -> list[str]

Collects only the string entries that contain search_string. When the search text is blank every string element is returned.

Docs: Module Reference

Example:

>>> from btx_lib_list import filter_contains
>>> filter_contains([], 'bc')
[]
>>> filter_contains(['abcd', 'def', 1, None], 'bc')
['abcd']
>>> filter_contains(['abc'], '')
['abc']
>>> filter_contains(['abc', 123], '')
['abc']

btx_lib_list.filter_fnmatch(elements: list[Any], search_pattern: str) -> list[str]

Applies fnmatch to each string element and returns the ones that match the shell-style pattern (non-strings are ignored).

Docs: Module Reference

Example:

>>> from btx_lib_list import filter_fnmatch
>>> filter_fnmatch([], 'a*')
[]
>>> filter_fnmatch(['abc', 'def', 1, None], 'a*')
['abc']

btx_lib_list.is_element_containing(elements: list[str], search_string: str) -> bool

Returns True if any string in elements contains search_string, enabling cheap guards before more expensive checks.

Docs: Module Reference

Example:

>>> from btx_lib_list import is_element_containing
>>> is_element_containing([], '')
False
>>> is_element_containing(['abcd', 'def', 1, None], '')
True
>>> is_element_containing(['abcd', 'def', 1, None], 'bc')
True
>>> is_element_containing(['abcd', 'def', 1, None], 'fg')
False

btx_lib_list.is_fnmatching(elements: list[Any], search_pattern: str) -> bool

Boolean probe that reports whether at least one string matches the given fnmatch pattern.

Docs: Module Reference

Example:

>>> from btx_lib_list import is_fnmatching
>>> is_fnmatching([], 'bc')
False
>>> is_fnmatching(['abcd', 'def', 1, None], '*bc*')
True
>>> is_fnmatching(['abcd', 'def', 1, None], '*1*')
False

btx_lib_list.is_fnmatching_one_pattern(elements: list[Any], search_patterns: list[str]) -> bool

Iterates over multiple patterns and returns True if any of them match one of the string elements.

Docs: Module Reference

Example:

>>> from btx_lib_list import is_fnmatching_one_pattern
>>> is_fnmatching_one_pattern([], [])
False
>>> is_fnmatching_one_pattern(['abcd', 'def', 1, None], [])
False
>>> is_fnmatching_one_pattern(['abcd', 'def', 1, None], ['*bc*', '*fg*'])
True
>>> is_fnmatching_one_pattern(['abcd', 'def', 1, None], ['*fg*', '*gh*'])
False

btx_lib_list.substract_all_keep_sorting(minuend: list[Any], subtrahend: list[Any]) -> list[Any]

Mutates minuend by removing every occurrence of values found in subtrahend while preserving the original order.

Docs: Module Reference

Example:

>>> from btx_lib_list import substract_all_keep_sorting
>>> substract_all_keep_sorting([], ['a'])
[]
>>> substract_all_keep_sorting(['a', 'a'], [])
['a', 'a']
>>> minuend = ['a', 'a', 'b']
>>> substract_all_keep_sorting(minuend, ['a', 'c'])
['b']

btx_lib_list.substract_all_unsorted_fast(minuend: list[Any], subtrahend: list[Any]) -> list[Any]

Creates a new list representing the set difference between the two lists (order is not guaranteed).

Docs: Module Reference

Example:

>>> from btx_lib_list import substract_all_unsorted_fast
>>> substract_all_unsorted_fast(['a', 'a', 'b'], ['a', 'c'])
['b']
>>> substract_all_unsorted_fast(['a', 'a', 'b'], ['b'])
['a']

btx_lib_list.ls_del_empty_elements(ls_elements: list[Any]) -> list[Any]

Drops any falsey values ("", None, 0, etc.) from the provided list.

Docs: Module Reference

Example:

>>> from btx_lib_list import ls_del_empty_elements
>>> ls_del_empty_elements([])
[]
>>> ls_del_empty_elements(['', ''])
[]
>>> ls_del_empty_elements(['', '', 'a', None, 'b'])
['a', 'b']
>>> ls_del_empty_elements(['   ', '', 'a', None, 'b'])
['   ', 'a', 'b']
>>> ls_del_empty_elements(['   ', '', 'a', None, 'b', 0])
['   ', 'a', 'b']

btx_lib_list.ls_double_quote_if_contains_blank(ls_elements: list[str]) -> list[str]

Wraps any string containing spaces in double quotes, keeping shell invocations safe.

Docs: Module Reference

Example:

>>> from btx_lib_list import ls_double_quote_if_contains_blank
>>> ls_double_quote_if_contains_blank([])
[]
>>> ls_double_quote_if_contains_blank([''])
['']
>>> ls_double_quote_if_contains_blank(['', 'double quote'])
['', '"double quote"']

btx_lib_list.ls_elements_replace_strings(ls_elements: list[Any], s_old: str, s_new: str) -> list[str]

Runs str.replace on each string element while leaving non-string entries untouched (return type stays list[str] to align with consumer expectations).

Docs: Module Reference

Example:

>>> from btx_lib_list import ls_elements_replace_strings
>>> ls_elements_replace_strings(['a', 'b', 'c', 1], 'a', 'z')
['z', 'b', 'c', 1]
>>> ls_elements_replace_strings([], 'a', 'z')
[]

btx_lib_list.ls_lstrip_list(list_of_strings: list[str], chars: str = "") -> list[str]

Returns a slice that omits leading entries equal to chars (defaults to empty strings).

Docs: Module Reference

Example:

>>> from btx_lib_list import ls_lstrip_list
>>> ls_lstrip_list(['', '', 'a', 'b', 'c', '', ''])
['a', 'b', 'c', '', '']
>>> ls_lstrip_list([])
[]

btx_lib_list.ls_rstrip_elements(ls_elements: list[str], chars: str | None = None) -> list[str]

Strips the specified characters from the right side of every string element.

Docs: Module Reference

Example:

>>> from btx_lib_list import ls_rstrip_elements
>>> ls_rstrip_elements(['  a', 'bbb', 'c   '])
['  a', 'bbb', 'c']
>>> ls_rstrip_elements([])
[]

btx_lib_list.ls_rstrip_list(list_of_strings: list[str], chars: str = "") -> list[str]

Removes trailing entries that match chars, returning the shortened list.

Docs: Module Reference

Example:

>>> from btx_lib_list import ls_rstrip_list
>>> ls_rstrip_list(['', '', 'a', 'b', 'c', '', ''])
['', '', 'a', 'b', 'c']
>>> ls_rstrip_list([])
[]

btx_lib_list.ls_strip_afz(ls_elements: list[str] | None) -> list[str]

Strips surrounding single or double quotes (and leading/trailing whitespace) from each string; returns [] when the input is None.

Docs: Module Reference

Example:

>>> from btx_lib_list import ls_strip_afz
>>> ls_strip_afz(['"  a"', "'bbb'", 'ccc', "   'ddd'"])
['  a', 'bbb', 'ccc', 'ddd']
>>> ls_strip_afz([])
[]
>>> ls_strip_afz(None)
[]

btx_lib_list.ls_strip_elements(ls_elements: list[str], chars: str | None = None) -> list[str]

Calls str.strip on every string element, returning the cleaned list.

Docs: Module Reference

Example:

>>> from btx_lib_list import ls_strip_elements
>>> ls_strip_elements(['  a', 'bbb', '   '])
['a', 'bbb', '']
>>> ls_strip_elements([])
[]

btx_lib_list.ls_strip_list(list_of_strings: list[str], chars: str = "") -> list[str]

Combines ls_lstrip_list and ls_rstrip_list to remove the sentinel from both ends.

Docs: Module Reference

Example:

>>> from btx_lib_list import ls_strip_list
>>> ls_strip_list(['', '', 'a', 'b', 'c', '', ''])
['a', 'b', 'c']

btx_lib_list.ls_substract(ls_minuend: list[Any], ls_subtrahend: list[Any]) -> list[Any]

Mutates ls_minuend by removing a single occurrence of each value found in ls_subtrahend.

Docs: Module Reference

Example:

>>> from btx_lib_list import ls_substract
>>> minuend = ['a', 'a', 'b']
>>> ls_substract(minuend, ['a', 'c'])
['a', 'b']

btx_lib_list.split_list_into_junks(source_list: list[Any], junk_size: int = sys.maxsize) -> list[list[Any]]

Splits source_list into slices of length junk_size (must be >= 1). The final chunk shares references with the original list to avoid copying.

Docs: Module Reference

Example:

>>> from btx_lib_list import split_list_into_junks
>>> split_list_into_junks([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], junk_size=11)
[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]
>>> split_list_into_junks([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], junk_size=3)
[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
>>> split_list_into_junks([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]

btx_lib_list.str_in_list_lower_and_de_double(list_of_strings: list[str]) -> list[str]

Returns a lowered, deduplicated set of strings (order is not preserved) for case-insensitive comparisons.

Docs: Module Reference

Example:

>>> from btx_lib_list import str_in_list_lower_and_de_double
>>> sorted(str_in_list_lower_and_de_double(['a', 'b', 'c', 'b', 'A']))
['a', 'b', 'c']
>>> str_in_list_lower_and_de_double([])
[]

btx_lib_list.str_in_list_non_case_sensitive(string: str, list_of_strings: list[str]) -> bool

Checks for membership regardless of case by comparing the lowercase variants.

Docs: Module Reference

Example:

>>> from btx_lib_list import str_in_list_non_case_sensitive
>>> str_in_list_non_case_sensitive('aba', ['abc', 'cde'])
False
>>> str_in_list_non_case_sensitive('aBa', ['abc', 'Aba'])
True

btx_lib_list.str_in_list_to_lower(list_of_strings: list[str]) -> list[str]

Lowercases every string element and returns the new list.

Docs: Module Reference

Example:

>>> from btx_lib_list import str_in_list_to_lower
>>> str_in_list_to_lower(['A', 'b', 'C'])
['a', 'b', 'c']
>>> str_in_list_to_lower([])
[]

btx_lib_list.strip_and_add_non_empty_args_to_list(*args: str | None) -> list[str]

Trims each argument, discards blanks/None, and returns the remaining non-empty strings in order.

Docs: Module Reference

Example:

>>> from btx_lib_list import strip_and_add_non_empty_args_to_list
>>> strip_and_add_non_empty_args_to_list('a  ', '  b', 'c', '', '  ')
['a', 'b', 'c']
>>> strip_and_add_non_empty_args_to_list()
[]

Performance Reference

Helper group Representative functions Complexity Notes
Deduplication deduplicate, str_in_list_lower_and_de_double O(n) Uses set; ordering and duplicate survivors are not preserved.
Filtering filter_contains, filter_fnmatch, del_elements_containing O(n) Single pass over inputs; non-strings skipped where appropriate.
Ordered subtraction substract_all_keep_sorting, ls_substract O(n·m) Relies on repeated list.remove; best for small collections.
Unordered subtraction substract_all_unsorted_fast O(n) Builds a set; removes duplicates of survivors.
Chunking split_list_into_junks O(n) Iterates once and reuses references for the final chunk.
String trimming ls_strip_elements, ls_rstrip_elements, ls_strip_list O(n) Applies string trimming per element.

n = length of the minuend and m = distinct subtrahend entries. For large lists prefer the unordered subtraction helper or precompute a lookup set.

Further Documentation

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

btx_lib_list-1.0.1.tar.gz (73.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

btx_lib_list-1.0.1-py3-none-any.whl (24.4 kB view details)

Uploaded Python 3

File details

Details for the file btx_lib_list-1.0.1.tar.gz.

File metadata

  • Download URL: btx_lib_list-1.0.1.tar.gz
  • Upload date:
  • Size: 73.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for btx_lib_list-1.0.1.tar.gz
Algorithm Hash digest
SHA256 04e0fc70ccb02d1ac8dc148acca73d3b4a238eae46cace8597102e2bc6bec517
MD5 4847e676a504c80a707636bc879441b3
BLAKE2b-256 cd08f485f1c4dbc00d939b7bd3d5352fc430bbb079eb67cb18de357583ea784c

See more details on using hashes here.

File details

Details for the file btx_lib_list-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: btx_lib_list-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 24.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for btx_lib_list-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 3f26f985668580b487cf0e908eb7bf5f828757e1f6a712e4a75f814ed863c95c
MD5 23135d20b2c548cf6153d6eab78c20f7
BLAKE2b-256 7c87b7e32bf28885433fe5cf93bb3a8dae0e0d243544f699310bc4aa07e170b7

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page