У меня есть набор
set(['booklet', '4 sheets', '48 sheets', '12 sheets'])
После сортировки я хочу, чтобы это было похоже
4 sheets,
12 sheets,
48 sheets,
booklet
Любая идея
Коротко и понятно:
sorted(data, key=lambda item: (int(item.partition(' ')[0])
if item[0].isdigit() else float('inf'), item))
Эта версия:
cmp
для sorted
(который не существует в Python 3) Если вы хотите, чтобы вывод был напечатан точно так, как описано в вашем примере, тогда:
data = set(['booklet', '4 sheets', '48 sheets', '12 sheets'])
r = sorted(data, key=lambda item: (int(item.partition(' ')[0])
if item[0].isdigit() else float('inf'), item))
print ',\n'.join(r)
Простой способ - разделить строки на числовые части и нечисловые части и использовать порядок сортировки кортежей Python для сортировки строк.
import re
tokenize = re.compile(r'(\d+)|(\D+)').findall
def natural_sortkey(string):
return tuple(int(num) if num else alpha for num, alpha in tokenize(string))
sorted(my_set, key=natural_sortkey)
наборы по своей сути неупорядочены. Вам нужно будет создать список с таким же содержимым и отсортировать его.
>>> a = set(['booklet', '4 sheets', '48 sheets', '12 sheets'])
>>> def ke(s):
i, sp, _ = s.partition(' ')
if i.isnumeric():
return int(i)
return float('inf')
>>> sorted(a, key=ke)
['4 sheets', '12 sheets', '48 sheets', 'booklet']
На основании ответа SilentGhost:
In [4]: a = set(['booklet', '4 sheets', '48 sheets', '12 sheets'])
In [5]: def f(x):
...: num = x.split(None, 1)[0]
...: if num.isdigit():
...: return int(num)
...: return x
...:
In [6]: sorted(a, key=f)
Out[6]: ['4 sheets', '12 sheets', '48 sheets', 'booklet']
Джефф Этвуд говорит о естественной сортировке и приводит пример одного из способов сделать это в Python. Вот мой вариант:
import re
def sorted_nicely( l ):
""" Sort the given iterable in the way that humans expect."""
convert = lambda text: int(text) if text.isdigit() else text
alphanum_key = lambda key: [ convert(c) for c in re.split('([0-9]+)', key) ]
return sorted(l, key = alphanum_key)
Используйте так:
s = set(['booklet', '4 sheets', '48 sheets', '12 sheets'])
for x in sorted_nicely(s):
print(x)
Вывод:
4 sheets
12 sheets
48 sheets
booklet
Одним из преимуществ этого метода является то, что он не работает, когда строки разделены пробелами. Он также будет работать для других разделителей, таких как точка в номерах версий (например, 1.9.1 предшествует 1.10.0).