Null и сортировка - PullRequest
       16

Null и сортировка

2 голосов
/ 13 января 2012

С помощью NaN можно получить список, который не будет правильно сортироваться:

--> NaN = float('nan')
--> spam = [1, 2, NaN, 3, NaN, 4, 5, 7, NaN]
--> sorted(spam)
[1, 2, nan, 3, nan, 4, 5, 7, nan]

Я создаю Null объект, который будет вести себя примерно так же, как NaN, с семантикой, согласно которой, если возвращаемый объект равен Null, его фактическое значение неизвестно. Объект Null также сможет взаимодействовать с любым другим типом объекта (int, float, str, bool и т. Д.), Но любое взаимодействие приведет к Null.

С точки зрения пуриста, если оно неизвестно, то результаты сравнения также неизвестны, поскольку фактическое значение может быть больше, меньше или равно значению, с которым сравнивается.

С практической точки зрения список с нулями, разбросанными повсюду, является болью в задней части.

Так что я сильно склоняюсь к осуществлению сравнений, чтобы нулевые объекты были меньше других объектов, поэтому они всегда будут сортироваться вместе.

Конечно, я всегда мог уклониться от этой проблемы и заставить пользователя реализовать пользовательские ключи сортировки.

Есть мысли / советы / критика / и т. Д.?

Ответы [ 2 ]

5 голосов
/ 13 января 2012

NaN обычно определяется как не сопоставимый ни с чем. Любые вычисления с участием NaN должны возвращать NaN.

На самом деле:

>>> print float('nan') == float('nan')
False

Да: NaN даже не то же самое, что и он сам. Есть веские причины для этого, хотя это действительно нелогично. Основная причина, вероятно, заключается в том, что, в отличие от всех других чисел, уникальный способ сортировки по возрастанию отсутствует. Должно ли прийти первым, последним, в конце? до или после бесконечности? Числа с плавающей точкой имеют пару странных вещей. Но, по крайней мере, нет никаких сомнений относительно -infty < -123 < -0 <= +0 < 123 < +infty.

Это «не число», так как же оно может быть больше, меньше или равно числу?

Конечно, вы можете определить пользовательскую функцию сравнения с четко определенным поведением сортировки для NaN значений:

def s(x, y):
  import math
  if math.isnan(x): return 1
  return cmp(x, y)

Обратите внимание, как я использую math.isnan. Эта функция имеет четкую семантику: сначала сортируются все числа, затем любое значение NaN.

1 голос
/ 14 января 2012

Если объект Null реализует поведение сравнения, другие методы (такие как индексирование) станут более сложными.Обратите внимание:

target = table.sql('select * where sales < 1000.00')

Если значения Null сравнивают <все другие объекты, тогда <code>target может иметь строки, в которых не было продаж (что не является целью).думаю, что практичность и чистота сводятся к одной и той же стороне: нулевые сравнения дают неизвестность.Пользователи должны будут решить, что делать со значениями Null, если они их получат.

...