Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Inconsistent behavior of sorted() with float('nan') in Python #134829

Closed as duplicate of#80276
@idanhazan

Description

@idanhazan

Bug report

Bug description:

Description

When using the built-in sorted() function on a list containing float('nan'), results are inconsistent and can break the expected ordering of sortable values (especially when filtering out NaN after sorting). The behavior appears non-deterministic depending on the position of NaN in the original list.


Reproducer

The following code illustrates the issue by iterating over all permutations of lists containing float('nan'), float('inf'), float('-inf'), and sometimes 0. After sorting, NaN

from itertools import permutations
from math import isnan

p_inf = float("inf")
n_inf = float("-inf")
nan = float("nan")

for permutation in permutations([p_inf, n_inf, nan]):
    sorted_permutation = sorted(permutation)
    filtered_nan = [x for x in sorted_permutation if not isnan(x)]
    is_sorted = filtered_nan == sorted(filtered_nan)
    print(
        "permutation:", permutation,
        "sorted_permutation:", sorted_permutation,
        "is_sorted:", is_sorted,
    )

# permutation: (inf, -inf, nan) sorted_permutation: [-inf, nan, inf] is_sorted: True
# permutation: (inf, nan, -inf) sorted_permutation: [inf, nan, -inf] is_sorted: False
# permutation: (-inf, inf, nan) sorted_permutation: [-inf, inf, nan] is_sorted: True
# permutation: (-inf, nan, inf) sorted_permutation: [-inf, nan, inf] is_sorted: True
# permutation: (nan, inf, -inf) sorted_permutation: [-inf, nan, inf] is_sorted: True
# permutation: (nan, -inf, inf) sorted_permutation: [nan, -inf, inf] is_sorted: True

for permutation in permutations([0, p_inf, n_inf, nan]):
    sorted_permutation = sorted(permutation)
    filtered_nan = [x for x in sorted_permutation if not isnan(x)]
    is_sorted = filtered_nan == sorted(filtered_nan)
    print(
        "permutation:", permutation,
        "sorted_permutation:", sorted_permutation,
        "is_sorted:", is_sorted,
    )

# permutation: (0, inf, -inf, nan) sorted_permutation: [-inf, 0, inf, nan] is_sorted: True
# permutation: (0, inf, nan, -inf) sorted_permutation: [0, inf, nan, -inf] is_sorted: False
# permutation: (0, -inf, inf, nan) sorted_permutation: [-inf, 0, inf, nan] is_sorted: True
# permutation: (0, -inf, nan, inf) sorted_permutation: [-inf, nan, inf, 0] is_sorted: False
# permutation: (0, nan, inf, -inf) sorted_permutation: [0, nan, -inf, inf] is_sorted: False
# permutation: (0, nan, -inf, inf) sorted_permutation: [0, nan, -inf, inf] is_sorted: False
# permutation: (inf, 0, -inf, nan) sorted_permutation: [-inf, nan, 0, inf] is_sorted: True
# permutation: (inf, 0, nan, -inf) sorted_permutation: [0, nan, -inf, inf] is_sorted: False
# permutation: (inf, -inf, 0, nan) sorted_permutation: [-inf, 0, inf, nan] is_sorted: True
# permutation: (inf, -inf, nan, 0) sorted_permutation: [-inf, nan, 0, inf] is_sorted: True
# permutation: (inf, nan, 0, -inf) sorted_permutation: [-inf, inf, nan, 0] is_sorted: False
# permutation: (inf, nan, -inf, 0) sorted_permutation: [inf, nan, -inf, 0] is_sorted: False
# permutation: (-inf, 0, inf, nan) sorted_permutation: [-inf, 0, inf, nan] is_sorted: True
# permutation: (-inf, 0, nan, inf) sorted_permutation: [-inf, 0, nan, inf] is_sorted: True
# permutation: (-inf, inf, 0, nan) sorted_permutation: [-inf, 0, inf, nan] is_sorted: True
# permutation: (-inf, inf, nan, 0) sorted_permutation: [-inf, inf, nan, 0] is_sorted: False
# permutation: (-inf, nan, 0, inf) sorted_permutation: [-inf, nan, 0, inf] is_sorted: True
# permutation: (-inf, nan, inf, 0) sorted_permutation: [-inf, nan, 0, inf] is_sorted: True
# permutation: (nan, 0, inf, -inf) sorted_permutation: [-inf, nan, 0, inf] is_sorted: True
# permutation: (nan, 0, -inf, inf) sorted_permutation: [-inf, nan, 0, inf] is_sorted: True
# permutation: (nan, inf, 0, -inf) sorted_permutation: [-inf, 0, nan, inf] is_sorted: True
# permutation: (nan, inf, -inf, 0) sorted_permutation: [-inf, nan, 0, inf] is_sorted: True
# permutation: (nan, -inf, 0, inf) sorted_permutation: [nan, -inf, 0, inf] is_sorted: True
# permutation: (nan, -inf, inf, 0) sorted_permutation: [0, nan, -inf, inf] is_sorted: False

Expected Behavior

Even if float('nan') is not orderable, its presence in the list should not cause the relative ordering of other comparable values (like -inf, 0, inf) to become incorrect. Ideally:

  • sorted() should consistently place NaN values in a predictable location (e.g., at the end).
  • The ordering of the remaining non-NaN values should always be correct.

CPython versions tested on:

3.13

Operating systems tested on:

Linux

Metadata

Metadata

Assignees

No one assigned

    Labels

    type-bugAn unexpected behavior, bug, or error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions