Closed as duplicate of#80276
Description
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 placeNaN
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