У меня есть наборКак сортировать буквенно-цифровой набор в питона
set(['booklet', '4 sheets', '48 sheets', '12 sheets'])
После сортировки я хочу, чтобы это выглядело как
4 sheets,
12 sheets,
48 sheets,
booklet
Любая идея пожалуйста
У меня есть наборКак сортировать буквенно-цифровой набор в питона
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)
>>> 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']
Jeff Atwood говорит о естественном роде и дает пример одного из способов сделать это в 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).
Hi Jeff, спасибо. Это именно то, что я искал. Удачи. – mmrs151
Можно ли изменить это для списка кортежей на основе первого значения в кортеже?Пример: '[('b', 0), ('0', 1), ('a', 2)]' сортируется в '[('0', 1), ('a', 2), ('b', 0)] ' – paragbaxi
Эта функция чувствительна к регистру. Верхние строки будут иметь приоритет. Чтобы исправить это, добавьте '.lower()' в 'key' в' re.split'. – zamber
Простым способом является разделение строк на числовые части и нечисловые части и использование порядка сортировки кортежей 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)
было высказано предположение о том, что я перепечатывать this answer здесь, так как он хорошо работает в этом случае также
from itertools import groupby
def keyfunc(s):
return [int(''.join(g)) if k else ''.join(g) for k, g in groupby(s, str.isdigit)]
sorted(my_list, key=keyfunc)
Демо:
>>> my_set = {'booklet', '4 sheets', '48 sheets', '12 sheets'}
>>> sorted(my_set, key=keyfunc)
['4 sheets', '12 sheets', '48 sheets', 'booklet']
Для Python3 необходимо изменить его немного (эта версия работает нормально в python2 тоже)
def keyfunc(s):
return [int(''.join(g)) if k else ''.join(g) for k, g in groupby('\0'+s, str.isdigit)]
Для людей, застрявших с предустановленным 2.4 версии Python, без замечательной функции sorted()
, быстрый способ сортировки наборы:
l = list(yourSet)
l.sort()
Это не отвечает на конкретный вопрос, указанный выше (12 sheets
поступит до 4 sheets
), но он может быть полезен людям, приезжающим из Google.
Вы должны проверить стороннюю библиотеку natsort. Его алгоритм является общим, поэтому он будет работать для большинства входных данных.
>>> import natsort
>>> your_list = set(['booklet', '4 sheets', '48 sheets', '12 sheets'])
>>> print ',\n'.join(natsort.natsorted(your_list))
4 sheets,
12 sheets,
48 sheets,
booklet
Общий ответ для сортировки любых чисел в любой позиции в массиве строк. Работает с Python 2 & 3.
def alphaNumOrder(string):
""" Returns all numbers on 5 digits to let sort the string with numeric order.
Ex: alphaNumOrder("a6b12.125") ==> "a00006b00012.00125"
"""
return ''.join([format(int(x), '05d') if x.isdigit()
else x for x in re.split(r'(\d+)', string)])
Пример:
s = ['a10b20','a10b1','a3','b1b1','a06b03','a6b2','a6b2c10','a6b2c5']
s.sort(key=alphaNumOrder)
s ===> ['a3', 'a6b2', 'a6b2c5', 'a6b2c10', 'a06b03', 'a10b1', 'a10b20', 'b1b1']
Часть ответа is from there
Отличный ответ Даниил – mmrs151