Как отсортировать альфу числовой набор в Python

У меня есть набор

set(['booklet', '4 sheets', '48 sheets', '12 sheets'])

После сортировки я хочу, чтобы это было похоже

4 sheets,
12 sheets,
48 sheets,
booklet

Любая идея

61
задан SilentGhost 19 April 2010 в 16:33
поделиться

6 ответов

Коротко и понятно:

sorted(data, key=lambda item: (int(item.partition(' ')[0])
                               if item[0].isdigit() else float('inf'), item))

Эта версия:

  • Работает в Python 2 и Python 3, потому что: {{1} }
    • Он не предполагает, что вы сравниваете строки и целые числа (что не работает в Python 3)
    • Он не использует параметр 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)
56
ответ дан 24 November 2019 в 16:59
поделиться

Простой способ - разделить строки на числовые части и нечисловые части и использовать порядок сортировки кортежей 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)
8
ответ дан 24 November 2019 в 16:59
поделиться

наборы по своей сути неупорядочены. Вам нужно будет создать список с таким же содержимым и отсортировать его.

0
ответ дан 24 November 2019 в 16:59
поделиться
>>> 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']
2
ответ дан 24 November 2019 в 16:59
поделиться

На основании ответа 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']
1
ответ дан 24 November 2019 в 16:59
поделиться

Джефф Этвуд говорит о естественной сортировке и приводит пример одного из способов сделать это в 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).

102
ответ дан 24 November 2019 в 16:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: