Как стать автором
Обновить

Комментарии 4

Вместо создания пользовательских объектов вы можете использовать кортежи (a, b), в которых a — значение для сравнения (приоритет), а b — исходное значение

Это не будет работать, если значения a совпадают. При равенстве a, сравниваться будут значения b, которые могут не поддерживать сравнения. Ещё и могут возникнуть чудеса:


sorted([(1, {}), (1, {}), (-1, {'x': 0})])
sorted([(1, {'x': 0}), (1, {})]) // TypeError

[x[1]['name'] for x in sorted(to_sort)]

Лучше выглядит так [x['name'] for _, x in sorted(to_sort)], не правда? :)


В этой ситуации можно пойти двумя путями. Можно использовать пользовательские объекты, которые поддерживают правильное сравнение

В прошлой подборке был совет использовать в этом случае functools.total_ordering. Если это неудобно, то возможно стоит сделать обёртку над коллекцией, поддерживающую сравнение по ключу.

Добавлю: кроме r'...' можно использовать R'...', во многих IDE подсветка для r идёт как regexp, а для R как для обычной строки.

во многих IDE подсветка для r идёт как regexp

Так оно и не зря, r'...' в большинстве случаев для реджексов и используется, чтобы не плодить слишком много двойных слешей.

a OP1 b OP2 c строго эквивалентно (a OP1 b) AND (b OP2 c)


Есть одно важное отличие, о котором стоило бы упомянуть: значения между операторами (в примере b) будут вычислены не более одного раза. Это может быть важно, если это там затратные вычисления или побочные эффекты:

>>> def f(x):
...     print(x)
...     return x
... 
>>> f(1) < f(2) == f(3) < f(4)
1
2
3
False
Зарегистрируйтесь на Хабре, чтобы оставить комментарий