Simple yet flexible natural sorting in Python.

Overview

natsort

Simple yet flexible natural sorting in Python.

NOTE: Please see the Deprecation Schedule section for changes in natsort version 7.0.0.

Quick Description

When you try to sort a list of strings that contain numbers, the normal python sort algorithm sorts lexicographically, so you might not get the results that you expect:

>>> a = ['2 ft 7 in', '1 ft 5 in', '10 ft 2 in', '2 ft 11 in', '7 ft 6 in']
>>> sorted(a)
['1 ft 5 in', '10 ft 2 in', '2 ft 11 in', '2 ft 7 in', '7 ft 6 in']

Notice that it has the order ('1', '10', '2') - this is because the list is being sorted in lexicographical order, which sorts numbers like you would letters (i.e. 'b', 'ba', 'c').

natsort provides a function natsorted that helps sort lists "naturally" ("naturally" is rather ill-defined, but in general it means sorting based on meaning and not computer code point). Using natsorted is simple:

>>> from natsort import natsorted
>>> a = ['2 ft 7 in', '1 ft 5 in', '10 ft 2 in', '2 ft 11 in', '7 ft 6 in']
>>> natsorted(a)
['1 ft 5 in', '2 ft 7 in', '2 ft 11 in', '7 ft 6 in', '10 ft 2 in']

natsorted identifies numbers anywhere in a string and sorts them naturally. Below are some other things you can do with natsort (also see the examples for a quick start guide, or the api for complete details).

Note: natsorted is designed to be a drop-in replacement for the built-in sorted function. Like sorted, natsorted does not sort in-place. To sort a list and assign the output to the same variable, you must explicitly assign the output to a variable:

>>> a = ['2 ft 7 in', '1 ft 5 in', '10 ft 2 in', '2 ft 11 in', '7 ft 6 in']
>>> natsorted(a)
['1 ft 5 in', '2 ft 7 in', '2 ft 11 in', '7 ft 6 in', '10 ft 2 in']
>>> print(a)  # 'a' was not sorted; "natsorted" simply returned a sorted list
['2 ft 7 in', '1 ft 5 in', '10 ft 2 in', '2 ft 11 in', '7 ft 6 in']
>>> a = natsorted(a)  # Now 'a' will be sorted because the sorted list was assigned to 'a'
>>> print(a)
['1 ft 5 in', '2 ft 7 in', '2 ft 11 in', '7 ft 6 in', '10 ft 2 in']

Please see Generating a Reusable Sorting Key and Sorting In-Place for an alternate way to sort in-place naturally.

Quick Examples

Sorting Versions

natsort does not actually comprehend version numbers. It just so happens that the most common versioning schemes are designed to work with standard natural sorting techniques; these schemes include MAJOR.MINOR, MAJOR.MINOR.PATCH, YEAR.MONTH.DAY. If your data conforms to a scheme like this, then it will work out-of-the-box with natsorted (as of natsort version >= 4.0.0):

>>> a = ['version-1.9', 'version-2.0', 'version-1.11', 'version-1.10']
>>> natsorted(a)
['version-1.9', 'version-1.10', 'version-1.11', 'version-2.0']

If you need to versions that use a more complicated scheme, please see these examples.

Sort Paths Like My File Browser (e.g. Windows Explorer on Windows)

Prior to natsort version 7.1.0, it was a common request to be able to sort paths like Windows Explorer. As of natsort 7.1.0, the function os_sorted has been added to provide users the ability to sort in the order that their file browser might sort (e.g Windows Explorer on Windows, Finder on MacOS, Dolphin/Nautilus/Thunar/etc. on Linux).

import os
from natsort import os_sorted
print(os_sorted(os.listdir()))
# The directory sorted like your file browser might show

Output will be different depending on the operating system you are on.

For users not on Windows (e.g. MacOS/Linux) it is strongly recommended to also install PyICU, which will help natsort give results that match most file browsers. If this is not installed, it will fall back on Python's built-in locale module and will give good results for most input, but will give poor restuls for special characters.

Sorting by Real Numbers (i.e. Signed Floats)

This is useful in scientific data analysis (and was the default behavior of natsorted for natsort version < 4.0.0). Use the realsorted function:

>>> from natsort import realsorted, ns
>>> # Note that when interpreting as signed floats, the below numbers are
>>> #            +5.10,                -3.00,            +5.30,              +2.00
>>> a = ['position5.10.data', 'position-3.data', 'position5.3.data', 'position2.data']
>>> natsorted(a)
['position2.data', 'position5.3.data', 'position5.10.data', 'position-3.data']
>>> natsorted(a, alg=ns.REAL)
['position-3.data', 'position2.data', 'position5.10.data', 'position5.3.data']
>>> realsorted(a)  # shortcut for natsorted with alg=ns.REAL
['position-3.data', 'position2.data', 'position5.10.data', 'position5.3.data']

Locale-Aware Sorting (or "Human Sorting")

This is where the non-numeric characters are also ordered based on their meaning, not on their ordinal value, and a locale-dependent thousands separator and decimal separator is accounted for in the number. This can be achieved with the humansorted function:

>>> a = ['Apple', 'apple15', 'Banana', 'apple14,689', 'banana']
>>> natsorted(a)
['Apple', 'Banana', 'apple14,689', 'apple15', 'banana']
>>> import locale
>>> locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')
'en_US.UTF-8'
>>> natsorted(a, alg=ns.LOCALE)
['apple15', 'apple14,689', 'Apple', 'banana', 'Banana']
>>> from natsort import humansorted
>>> humansorted(a)  # shortcut for natsorted with alg=ns.LOCALE
['apple15', 'apple14,689', 'Apple', 'banana', 'Banana']

You may find you need to explicitly set the locale to get this to work (as shown in the example). Please see locale issues and the Optional Dependencies section below before using the humansorted function.

Further Customizing Natsort

If you need to combine multiple algorithm modifiers (such as ns.REAL, ns.LOCALE, and ns.IGNORECASE), you can combine the options using the bitwise OR operator (|). For example,

>>> a = ['Apple', 'apple15', 'Banana', 'apple14,689', 'banana']
>>> natsorted(a, alg=ns.REAL | ns.LOCALE | ns.IGNORECASE)
['Apple', 'apple15', 'apple14,689', 'Banana', 'banana']
>>> # The ns enum provides long and short forms for each option.
>>> ns.LOCALE == ns.L
True
>>> # You can also customize the convenience functions, too.
>>> natsorted(a, alg=ns.REAL | ns.LOCALE | ns.IGNORECASE) == realsorted(a, alg=ns.L | ns.IC)
True
>>> natsorted(a, alg=ns.REAL | ns.LOCALE | ns.IGNORECASE) == humansorted(a, alg=ns.R | ns.IC)
True

All of the available customizations can be found in the documentation for the ns enum.

You can also add your own custom transformation functions with the key argument. These can be used with alg if you wish.

>>> a = ['apple2.50', '2.3apple']
>>> natsorted(a, key=lambda x: x.replace('apple', ''), alg=ns.REAL)
['2.3apple', 'apple2.50']

Sorting Mixed Types

You can mix and match int, float, and str (or unicode) types when you sort:

>>> a = ['4.5', 6, 2.0, '5', 'a']
>>> natsorted(a)
[2.0, '4.5', '5', 6, 'a']
>>> # On Python 2, sorted(a) would return [2.0, 6, '4.5', '5', 'a']
>>> # On Python 3, sorted(a) would raise an "unorderable types" TypeError

Handling Bytes on Python 3

natsort does not officially support the bytes type on Python 3, but convenience functions are provided that help you decode to str first:

>>> from natsort import as_utf8
>>> a = [b'a', 14.0, 'b']
>>> # On Python 2, natsorted(a) would would work as expected.
>>> # On Python 3, natsorted(a) would raise a TypeError (bytes() < str())
>>> natsorted(a, key=as_utf8) == [14.0, b'a', 'b']
True
>>> a = [b'a56', b'a5', b'a6', b'a40']
>>> # On Python 2, natsorted(a) would would work as expected.
>>> # On Python 3, natsorted(a) would return the same results as sorted(a)
>>> natsorted(a, key=as_utf8) == [b'a5', b'a6', b'a40', b'a56']
True

Generating a Reusable Sorting Key and Sorting In-Place

Under the hood, natsorted works by generating a custom sorting key using natsort_keygen and then passes that to the built-in sorted. You can use the natsort_keygen function yourself to generate a custom sorting key to sort in-place using the list.sort method.

>>> from natsort import natsort_keygen
>>> natsort_key = natsort_keygen()
>>> a = ['2 ft 7 in', '1 ft 5 in', '10 ft 2 in', '2 ft 11 in', '7 ft 6 in']
>>> natsorted(a) == sorted(a, key=natsort_key)
True
>>> a.sort(key=natsort_key)
>>> a
['1 ft 5 in', '2 ft 7 in', '2 ft 11 in', '7 ft 6 in', '10 ft 2 in']

All of the algorithm customizations mentioned in the Further Customizing Natsort section can also be applied to natsort_keygen through the alg keyword option.

Other Useful Things

FAQ

How do I debug natsort.natsorted()?

The best way to debug natsorted() is to generate a key using natsort_keygen() with the same options being passed to natsorted. One can take a look at exactly what is being done with their input using this key - it is highly recommended to look at this issue describing how to debug for how to debug, and also to review the How Does Natsort Work? page for why natsort is doing that to your data.

If you are trying to sort custom classes and running into trouble, please take a look at https://github.com/SethMMorton/natsort/issues/60. In short, custom classes are not likely to be sorted correctly if one relies on the behavior of __lt__ and the other rich comparison operators in their custom class - it is better to use a key function with natsort, or use the natsort key as part of your rich comparison operator definition.

natsort gave me results I didn't expect, and it's a terrible library!
Did you try to debug using the above advice? If so, and you still cannot figure out the error, then please file an issue.
How does natsort work?

If you don't want to read How Does Natsort Work?, here is a quick primer.

natsort provides a key function that can be passed to list.sort() or sorted() in order to modify the default sorting behavior. This key is generated on-demand with the key generator natsort.natsort_keygen(). natsort.natsorted() is essentially a wrapper for the following code:

>>> from natsort import natsort_keygen
>>> natsort_key = natsort_keygen()
>>> sorted(['1', '10', '2'], key=natsort_key)
['1', '2', '10']

Users can further customize natsort sorting behavior with the key and/or alg options (see details in the Further Customizing Natsort section).

The key generated by natsort_keygen always returns a tuple. It does so in the following way (some details omitted for clarity):

  1. Assume the input is a string, and attempt to split it into numbers and non-numbers using regular expressions. Numbers are then converted into either int or float.
  2. If the above fails because the input is not a string, assume the input is some other sequence (e.g. list or tuple), and recursively apply the key to each element of the sequence.
  3. If the above fails because the input is not iterable, assume the input is an int or float, and just return the input in a tuple.

Because a tuple is always returned, a TypeError should not be common unless one tries to do something odd like sort an int against a list.

Shell script

natsort comes with a shell script called natsort, or can also be called from the command line with python -m natsort.

Requirements

natsort requires Python 3.5 or greater. Python 3.4 is unofficially supported, meaning that support has not been removed, but it is no longer tested.

Optional Dependencies

fastnumbers

The most efficient sorting can occur if you install the fastnumbers package (version >=2.0.0); it helps with the string to number conversions. natsort will still run (efficiently) without the package, but if you need to squeeze out that extra juice it is recommended you include this as a dependency. natsort will not require (or check) that fastnumbers is installed at installation.

PyICU

It is recommended that you install PyICU if you wish to sort in a locale-dependent manner, see https://natsort.readthedocs.io/en/master/locale_issues.html for an explanation why.

Installation

Use pip!

$ pip install natsort

If you want to install the Optional Dependencies, you can use the "extras" notation at installation time to install those dependencies as well - use fast for fastnumbers and icu for PyICU.

# Install both optional dependencies.
$ pip install natsort[fast,icu]
# Install just fastnumbers
$ pip install natsort[fast]

How to Run Tests

Please note that natsort is NOT set-up to support python setup.py test.

The recommended way to run tests is with tox. After installing tox, running tests is as simple as executing the following in the natsort directory:

$ tox

tox will create virtual a virtual environment for your tests and install all the needed testing requirements for you. You can specify a particular python version with the -e flag, e.g. tox -e py36. Static analysis is done with tox -e flake8. You can see all available testing environments with tox --listenvs.

If you do not wish to use tox, you can install the testing dependencies with the dev/requirements.txt file and then run the tests manually using pytest.

$ pip install -r dev/requirements.txt
$ python -m pytest

Note that above I invoked python -m pytest instead of just pytest - this is because the former puts the CWD on sys.path.

How to Build Documentation

If you want to build the documentation for natsort, it is recommended to use tox:

$ tox -e docs

This will place the documentation in build/sphinx/html. If you do not which to use tox, you can do the following:

$ pip install sphinx sphinx_rtd_theme
$ python setup.py build_sphinx

Deprecation Schedule

Dropped Python 2.7 Support

natsort version 7.0.0 dropped support for Python 2.7.

The version 6.X branch will remain as a "long term support" branch where bug fixes are applied so that users who cannot update from Python 2.7 will not be forced to use a buggy natsort version (bug fixes will need to be requested; by default only the 7.X branch will be updated). New features would not be added to version 6.X, only bug fixes.

Dropped Deprecated APIs

In natsort version 6.0.0, the following APIs and functions were removed

  • number_type keyword argument (deprecated since 3.4.0)
  • signed keyword argument (deprecated since 3.4.0)
  • exp keyword argument (deprecated since 3.4.0)
  • as_path keyword argument (deprecated since 3.4.0)
  • py3_safe keyword argument (deprecated since 3.4.0)
  • ns.TYPESAFE (deprecated since version 5.0.0)
  • ns.DIGIT (deprecated since version 5.0.0)
  • ns.VERSION (deprecated since version 5.0.0)
  • versorted() (discouraged since version 4.0.0, officially deprecated since version 5.5.0)
  • index_versorted() (discouraged since version 4.0.0, officially deprecated since version 5.5.0)

In general, if you want to determine if you are using deprecated APIs you can run your code with the following flag

$ python -Wdefault::DeprecationWarning my-code.py

By default DeprecationWarnings are not shown, but this will cause them to be shown. Alternatively, you can just set the environment variable PYTHONWARNINGS to "default::DeprecationWarning" and then run your code.

Author

Seth M. Morton

History

Please visit the changelog on GitHub or in the documentation.

Comments
  • '_' can't be right sorted in Windows

    '_' can't be right sorted in Windows

    In windows OS, I want to sorted files in a content with a natural way. But I found your code seems to be not well done in windows. The '_' is sorted after number '0-9'. But in windows OS, the '_' is showed before number '0-9'.

    feature help wanted good first issue 
    opened by oneTaken 27
  • TypeError when trying to sort a string of a number and a string

    TypeError when trying to sort a string of a number and a string

    Python 3.3 and Python 3.4 fail to sort collections that contain strings that are also numbers:

    >>> import natsort
    >>> natsort.natsorted(('a', '1'))
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/home/kwpolska/virtualenvs/nikola-py3/lib/python3.4/site-packages/natsort/natsort.py", line 247, in natsorted
        return sorted(seq, key=lambda x: natsort_key(key(x),
    TypeError: unorderable types: float() < str()
    

    This works just fine in Python 2.7.6.

    via getnikola/nikola#1275 (cc @devurandom)

    bug feature 
    opened by Kwpolska 18
  • Deploy to PyPI from Travis CI

    Deploy to PyPI from Travis CI

    This should help make releasing easier.

    • Deploy non-tagged builds to Test PyPI
    • Deploy tagged builds to live PyPI

    Will only trigger when run from the SethMMorton/natsort repo, on master, so not for forks or PRs.

    The on: section shows the conditions for triggering an upload. This should be set up so only a single build job qualifies.

    Right now, there's only a single Python 3.8 job, so select on python: 3.8. If 3.7 and 3.8 are switched, this can also so there's only a single 3.7. It's possible to select on other conditions too:

    https://docs.travis-ci.com/user/deployment/#conditional-releases-with-on

    skip_existing: true should in any case prevent trying to re-upload existing ones.

    TODO:

    1. Add an API token called (say) natsort-ci at https://test.pypi.org/manage/account/token/
    2. On the command line, install the Travis Client
    3. Run travis encrypt
    4. Paste in the token from step 1, it begins pypi-
    5. Ctrl-D to end
    6. Add the encrypted value as the first password: secure: "TODO" value
    7. Repeat for production PyPI, put the encrypted value as the second "TODO"

    More info on PyPI API tokens: https://pypi.org/help/#apitoken

    opened by hugovk 17
  • Added a natcmp() for comparing in Python 2

    Added a natcmp() for comparing in Python 2

    Python 2 allowed objects to override the cmp magic method in order to sort and compare objects efficiently, this pull request adds support to those who still use python 2 and want to make their objects comparable easily.

    feature 
    opened by rinslow 16
  • Upload a wheel to PyPI

    Upload a wheel to PyPI

    You can achieve this by installing the wheel package and running python setup.py register bdist_wheel upload in your natsort directory. It can also be combined with your existing source distribution uploads like so python setup.py register sdist bdist_wheel upload.

    This change makes the generated wheel compatible with both python 2 and 3.

    usability 
    opened by ghickman 14
  • versorted should follow SemVer rules

    versorted should follow SemVer rules

    Minimum, Complete, Verifiable Example

    In [1]: import natsort
    
    In [2]: a = ['1.0.0-alpha', '1.0.0-alpha.1', '1.0.0-alpha.beta', '1.0.0-beta', '1.0.0-beta.2', '1.0.0
       ...: -beta.11', '1.0.0-rc.1', '1.0.0']
    
    In [3]: natsort.versorted(a)
    Out[3]: 
    ['1.0.0',
     '1.0.0-alpha',
     '1.0.0-alpha.1',
     '1.0.0-alpha.beta',
     '1.0.0-beta',
     '1.0.0-beta.2',
     '1.0.0-beta.11',
     '1.0.0-rc.1']
    
    In [4]: natsort.__version__
    Out[4]: '5.3.2'
    
    

    According to https://semver.org/, 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0. natsort puts the 1.0.0 is in the wrong place.

    Error message, Traceback, Desired behavior, Suggestion, Request, or Question

    There is a useful hack to make this work, but that should not be needed for a function called versorted. It should handle this out-of-the-box.

    This would be a breaking change, and might require updating the natsort major version.

    wontfix 
    opened by SethMMorton 12
  • Modify sort order of upper- and lower-case letters with ns.LOCALE?

    Modify sort order of upper- and lower-case letters with ns.LOCALE?

    Here's another I just found. However, using TYPESAFE corrects it.

    kfunc = natsort.natsort_keygen( alg=( natsort.ns.LOCALE ) )
    sorted( [ '10-12','10th'], key=kfunc)
    Traceback (most recent call last):
      File "<string>", line 1, in <fragment>
        builtins.TypeError: unorderable types: bytes() < float()
    ksafe = natsort.natsort_keygen(alg=(natsort.ns.LOCALE|natsort.ns.TYPESAFE))
    sorted( [ '10-12','10th'], key=ksafe)
    ['10-12', '10th']
    

    I am slightly concerned because I noted a comment in the code about TYPESAFE being in some way expensive to execute and I am sorting quite large tables.

    question 
    opened by tallforasmurf 12
  • Strange result for specific number strings using Dutch locale

    Strange result for specific number strings using Dutch locale

    Actual behavior Human sorting ['461761', '462166'] using the Dutch locale gives the wrong result ['462166', '461761'].

    Expected behavior The result should be ['461761', '462166'].

    Environment 1:

    • Python 3.8.1
    • Mac OS X 10.14.6
    • PyICU installed
    • Locale set to 'nl_NL'

    Environment 2:

    • Python 3.8.0
    • Windows 7 SP1
    • PyICU not installed
    • Locale set to 'nl-NL'

    Environment 3:

    • Python 3.8.1
    • FreeBSD 12.1
    • PyICU not installed
    • Locale set to 'nl_NL.ISO8859-1'

    To reproduce

    >>> import locale
    >>> locale.setlocale(locale.LC_ALL, 'Dutch') # replace 'Dutch' as appropriate
    >>> from natsort import humansorted
    >>> humansorted(['461761', '462166'])
    ['462166', '461761']
    
    bug 
    opened by thijsvandien 11
  • Request for option to modify case-sensitivity when sorting

    Request for option to modify case-sensitivity when sorting

    Hello, hopefully this is in the right place...

    It seems that the library behaves weirdly with string case. For example, A a B b will be sorted as A B a b rather than A a B b, not sure if this is intended or not, but it differs from jquery natural sort so it gives some problems. An easy fix is to use a lambda which casts the string to lower case but I'm wondering if it is possible to have a setting to change this behaviour.

    feature 
    opened by cristianocoelho 11
  • Wrong ordering of ordered pandas categoricals

    Wrong ordering of ordered pandas categoricals

    Describe the bug

    There is a separate dtype in pandas - Categorical, which can optionally be turned to sortable with arbitrary order of elements. It is very convenient when order of elements should be fixed and can't be described by any logic.

    Expected behavior

    natsorted should when dealing with ordered categorical columns should just use comparison of elements defined by ordering.

    Environment (please complete the following information):

    • Python Version: 3.7
    • OS [e.g. Windows, Fedora] ubuntu, macos

    To Reproduce

    n [1]: import pandas as pd
    
    # create a series with categorical dtype. Note a special flag 'ordered', 
    # most cateoricals are unordered and those are handled by natsort ok,  but not ordered
    In [2]: x = pd.Categorical(['a', 'b', 'c', 'b', 'a', 'c'], categories=['c', 'b', 'a'], ordered=True)
    
    In [3]: x.sort_values()
    Out[3]:
    ['c', 'c', 'b', 'b', 'a', 'a']
    Categories (3, object): ['c' < 'b' < 'a']
    
    In [4]: from natsort import natsorted
    
    In [5]: natsorted(x)
    Out[5]: ['a', 'a', 'b', 'b', 'c', 'c']
    
    # expected output is ['c', 'c', 'b', 'b', 'a', 'a']
    
    opened by arogozhnikov 10
  • Type hints

    Type hints

    The library does not yet provide type hints for use with Mypy for example. It would be great to get rid of # type: ignore and enjoy the additional safety.

    feature 
    opened by thijsvandien 9
  • os_sorted: only convert input to str if necessary

    os_sorted: only convert input to str if necessary

    See https://github.com/SethMMorton/natsort/issues/157

    I ran some benchmarks and I get a consistent 20% improvement when the inputs are Path already. Both for small lists and large lists (I tested lists with 10 and 10 000 items).

    from random import shuffle
    from pathlib import Path
    from timeit import repeat
    
    from natsort import os_sorted
    
    INPATH = "<path>"
    paths = list(Path(INPATH).rglob("*"))
    print(len(paths))
    shuffle(paths)
    
    # use smaller `number` for larger lists
    print(min(repeat("os_sorted(paths)", repeat=10, number=1000, globals={"os_sorted": os_sorted, "paths": paths})))
    

    I cannot run the test suite sadly since I get lots of locale.Error: unsupported locale setting errors.

    opened by Dobatymo 3
  • Improve os_sorted performance by avoiding `Path` roundtrips

    Improve os_sorted performance by avoiding `Path` roundtrips

    Describe the feature or enhancement When using os_sorted on a list of Path objects they are converted to string and then back to Path.

    Provide a concrete example of how the feature or enhancement will improve natsort Avoiding this roundtrip should improve performance.

    Would you be willing to submit a Pull Request for this feature? I am not really familiar with the library yet. It looks like the conversion here https://github.com/SethMMorton/natsort/blob/5c52a8888c2cb0c3f08192e2684851e0253b4437/natsort/natsort.py#L672 could be moved to the else branch here https://github.com/SethMMorton/natsort/blob/5c52a8888c2cb0c3f08192e2684851e0253b4437/natsort/utils.py#L898 instead

    opened by Dobatymo 1
  • Set which OS to sort by in `os_sorted`

    Set which OS to sort by in `os_sorted`

    Describe the feature or enhancement use an optional input to os_sorted that allows sorting based on any operating system even when you are not using that operating system e.g. os_sorted(my_list, force_os = 'windows') will sort based on a windows machine even when in Unix/mac

    Provide a concrete example of how the feature or enhancement will improve natsort If people need to replicate results in one operating system using code created in another operating system which uses os_sorted then this would be useful. I have a project where I work on cloud drives across machines and happen to use os_sorted, I would love to replace some stuff that already integrates os_sorted. alternatively could you show me how to do this using the os_sort_keygen? or some other method?

    Would you be willing to submit a Pull Request for this feature? I don't have the experience to do this so I am sorry but I can't help here

    thank you for your help and useful package

    feature help wanted 
    opened by PhillipMaire 8
  • Some values don't sort in a consistent order

    Some values don't sort in a consistent order

    The output of natsorted depends on the input order in many cases:

    >>> def sorted_both_ways(a, b, sorted=natsort.natsorted):
    ...     return sorted([a, b]), sorted([b, a])
    ...
    >>> sorted_both_ways(1, '1')
    ([1, '1'], ['1', 1])
    >>> sorted_both_ways('1', '01')
    (['1', '01'], ['01', '1'])
    >>> sorted_both_ways(float('-inf'), float('nan'))
    ([-inf, nan], [nan, -inf])
    >>> sorted_both_ways(float('nan'), None)
    ([nan, None], [None, nan])
    

    In the case of NaNs, there's a flag to sort them at the end instead of the beginning, but they don't sort at the end with it and don't sort at the beginning without it, even if the input is only floats. Code that depends on NaN sorting order is likely to check the 0th or -1th item of the output to see whether there are any NaNs, which leads to hard-to-find bugs with the current behavior.

    In the case of '1' and '01', I don't think the order matters, but I think there should be an order. StrCmpLogicalW sorts 01 < 1 < 02 < 2; I don't claim that's the best order, but it's consistent and matches at least one widely used tool.

    In the case of 1 and '1', my preference would be that it raise TypeError. People who pass the FLOAT flag are working around some horrible brokenness elsewhere in their system, and deserve all the bad things that happen to them, but I have a hard time believing that anyone needs/wants the current int-only behavior without the flag. The library already raises TypeError when sorting [1, b'1'], so it's not like it's aiming to work with arbitrary mixtures of heterogeneous values.

    opened by benrg 2
Yet another retry utility in Python

Yet another retry utility in Python, avereno being the Malagasy word for retry.

Haute École d'Informatique de Madagascar 4 Nov 2, 2021
Simple python module to get the information regarding battery in python.

Battery Stats A python3 module created for easily reading the current parameters of Battery in realtime. It reads battery stats from /sys/class/power_

Shreyas Ashtamkar 5 Oct 21, 2022
A python package containing all the basic functions and classes for python. From simple addition to advanced file encryption.

A python package containing all the basic functions and classes for python. From simple addition to advanced file encryption.

PyBash 11 May 22, 2022
A Python utility belt containing simple tools, a stdlib like feel, and extra batteries. Hashing, Caching, Timing, Progress, and more made easy!

Ubelt is a small library of robust, tested, documented, and simple functions that extend the Python standard library. It has a flat API that all behav

Jon Crall 638 Dec 13, 2022
A simple Python app that generates semi-random chord progressions.

chords-generator A simple Python app that generates semi-random chord progressions.

null 53 Sep 7, 2022
A simple and easy to use Spam Bot made in Python!

This is a simple spam bot made in python. You can use to to spam anyone with anything on any platform.

null 7 Sep 8, 2022
Simple collection of GTPS Flood in Python.

GTPS Flood Simple collection of GTPS Flood in Python. NOTE Give me credit if you use this source, don't trade/sell this tool, And USE AT YOUR OWN RISK

PhynX 6 Dec 7, 2021
A set of Python scripts to surpass human limits in accomplishing simple tasks.

Human benchmark fooler Summary A set of Python scripts with Selenium designed to surpass human limits in accomplishing simple tasks available on https

Bohdan Dudchenko 3 Feb 10, 2022
A simple gpsd client and python library.

gpsdclient A small and simple gpsd client and library Installation Needs Python 3 (no other dependencies). If you want to use the library, use pip: pi

Thomas Feldmann 33 Nov 24, 2022
Simple Python tool that generates a pseudo-random password with numbers, letters, and special characters in accordance with password policy best practices.

Simple Python tool that generates a pseudo-random password with numbers, letters, and special characters in accordance with password policy best practices.

Joe Helle 7 Mar 25, 2022
A simple python implementation of Decision Tree.

DecisionTree A simple python implementation of Decision Tree, using Gini index. Usage: import DecisionTree node = DecisionTree.trainDecisionTree(lab

null 1 Nov 12, 2021
A simple tool to extract python code from a Jupyter notebook, and then run pylint on it for static analysis.

Jupyter Pylinter A simple tool to extract python code from a Jupyter notebook, and then run pylint on it for static analysis. If you find this tool us

Edmund Goodman 10 Oct 13, 2022
Simple RGB to HEX game made in python

Simple RGB to HEX game made in python

null 5 Aug 26, 2022
A simple and easy to use collection of random python functions.

A simple and easy to use collection of random python functions.

Diwan Mohamed Faheer 1 Nov 17, 2021
A simple dork generator written in python that outputs dorks with the domain extensions you enter

Dork Gen A simple dork generator written in python that outputs dorks with the domain extensions you enter in a ".txt file". Usage The code is pretty

Z3NToX 4 Oct 30, 2022
Shypan, a simple, easy to use, full-featured library written in Python.

Shypan, a simple, easy to use, full-featured library written in Python.

ShypanLib 4 Dec 8, 2021
🌲 A simple BST (Binary Search Tree) generator written in python

Tree-Traversals (BST) ?? A simple BST (Binary Search Tree) generator written in python Installation Use the package manager pip to install BST. Usage

Jan Kupczyk 1 Dec 12, 2021
A simple python script to generate an iCalendar file for the university classes.

iCal Generator This is a simple python script to generate an iCalendar file for the university classes. Installation Clone the repository git clone ht

Foad Rashidi 2 Sep 1, 2022
A simple example for calling C++ functions in Python by `ctypes`.

ctypes-example A simple example for calling C++ functions in Python by ctypes. Features call C++ function int bar(int* value, char* msg) with argumene

Yusu Pan 3 Nov 23, 2022